Forum Informatica Unict

LAUREA TRIENNALE (D.M. 270/04) => Programmazione 1, 9 CFU => Topic started by: sonj on 14-02-2011, 18:30:00



Title: Aiuto esercizio
Post by: sonj on 14-02-2011, 18:30:00
salve a tutti... nello stato di una classe c'era una cosa del genere:
#totaleC:int
il mio problema è implementarlo,in quanto ti chiede che deve contare il numero di istanze si classe C,che sarà la classe successivamente ereditata.
come faccio a contare le istanze di questa classe? devo farlo all'interno del costruttore o devo scrivermi un medoto apparte?


Title: Re:Aiuto esercizio
Post by: Impact on 14-02-2011, 19:10:46
Internamente alla classe C, nel costruttore sempre di C, richiamando la variabile di istanza e incrementarla nel seguente modo: this.totaleC++


Title: Re:Aiuto esercizio
Post by: Luxandro on 14-02-2011, 19:13:22
Quindi il costruttore della classe C sarà una cosa di questo tipo?

Code:
public C (int x, int w, double d, int z)
{

super (x, w, d);
z = this.totaleC ++;
}


Title: Re:Aiuto esercizio
Post by: Impact on 14-02-2011, 19:14:47
No, sarà così:
Code:
public C (int x, int w, double d, int z)
{

super (x, w, d);
this.z=z;
this.totaleC ++;
}


Title: Re:Aiuto esercizio
Post by: Luxandro on 14-02-2011, 19:15:12
Una domanda:  super e this si usano esclusivamente all'interno del costruttore; o mi sbaglio?  .penso


Title: Re:Aiuto esercizio
Post by: Luxandro on 14-02-2011, 19:16:16
No, sarà così:
Code:
public C (int x, int w, double d, int z)
{

super (x, w, d);
this.z=z;
this.totaleC ++;
}

Cosi ogni volta che viene istanziata la classe C la variabile di istanza si incrementa!  Giusto  :-)|


Grazie mille!


Title: Re:Aiuto esercizio
Post by: Impact on 14-02-2011, 19:20:32
this, in questo caso è un riferimento ad un costruttore dell'oggetto è quindi possibile in un costruttore chiamare un costruttore diverso della classe stessa, a patto che l'invocazione sia la prima istruzione del costruttore e che il costruttore sia diverso da quello attuale. il super viene usato pure per invocare, però serve per invocare quelli della superclasse.


Title: Re:Aiuto esercizio
Post by: Luxandro on 14-02-2011, 19:28:45
this, in questo caso è un riferimento ad un costruttore dell'oggetto è quindi possibile in un costruttore chiamare un costruttore diverso della classe stessa, a patto che l'invocazione sia la prima istruzione del costruttore e che il costruttore sia diverso da quello attuale. il super viene usato pure per invocare, però serve per invocare quelli della superclasse.

Sostanzialmente

Code:
this.z = z;

richiama la variabile d'instanza della classe alla quale appartiene

Code:
this.totaleC ++;

richiama una variabile d'instanza della classe progenitrice

Il super , per quanto ho capito, serve ad invocare il costruttore della superclasse...Giusto?  .penso

Non ho invece ben compreso l'esatto valore del this    :-)|


Title: Re:Aiuto esercizio
Post by: ɹǝǝuıƃuǝsɹǝʌǝɹ on 14-02-2011, 20:03:04
Una domanda:  super e this si usano esclusivamente all'interno del costruttore; o mi sbaglio?  .penso
Rispettivamente sì e no.

Risposta breve: super indica l'invocazione (eventualmente a risalita -opposto di cascata- qualora anche i singoli costruttori ne prevedano l'uso) del costruttore della classe che sta immediatamente più in alto nella gerarchia in cui si trova quella in cui è scritto il metodo che lo contiene, oppure il tentativo di accedere a una variabile membro/metodo della classe genitore.

Risposta lunga: super si può (e a volte si deve) usare esattamente in due contesti, e in due modi completamente diversi:

1) nel costruttore di una classe figlia:
nel codice di tale costruttore il nome "super" può essere usato nel seguente modo:
super (par1, par2, ..., parN)
ove
par1 è di tipo typ1,
par2 è di tipo typ2,
...,
parN è di tipo typN
con \text{N}\in\mathbb{N}
ed esiste un costruttore esplicito nella classe madre che come parametri accetta esattamente (typ1', typ2', ..., typ3') con
typ1' fra le classi antenate di (eventualmente coincidente con) typ1,
typ2' fra le classi antenate di (eventualmente coincidente con) typ2,
...
typN' fra le classi antenate di (eventualmente coincidente con) typN.
Più in generale, invece di classi antenate (eventualmente coincidenti con), si dovrebbe parlare formalmente di "sovratipo" (eventualmente coincidente), ma questo riguarda la teoria dei tipi in Java (ed è un po' più complicato che parlare di sovraclassi, ma per adesso non vi interessa .wink...)

Normalmente la JVM sceglie il costruttore tale che la somma delle lunghezze delle gerarchie di typ1, typ2, ..., typN più grande (cioè quello che, fra tutti i possibili, ha i tipi specificati in modo più "particolare", piuttosto che in modo più "generale"), ma ci possono essere casi di ambiguità che il compilatore (prima ancora del runtime) di suggerirà di eliminare, pena il fallimento della compilazione  :boh.

In questo caso, comunque, l'invocazione a super (...) va fatta necessariamente prima di ogni altra istruzione (comprese eventuali altre istruzioni super (...), il che comporta che due istruzioni super (...) consecutive non possono essere compilate in quando la seconda e le successive non sarebbero le prime  :nono).

Seconda limitazione importante: ogni nostro costruttore che non comprende alcuna invocazione super (...) tenta sempre di eseguire super ();, nel caso in cui noi omettiamo di scriverlo, quando esegue qualsiasi costruttore di una classe.
Nel caso in cui, quindi, viene compilato un costruttore che non ha alcuna invocazione di "super (...)", il compilatore in automatico inserirà il codice "super ();" senza che noi lo vediamo, e compilerà tale codice.
Il problema è che "super ();", per come ho poc'anzi affermato, richiama il costruttore "esplicito" (cioè scritto da noi, non quello che ancora non esiste e, in caso, sarà aggiunto dal compilatore); se tale costruttore "esplicito" (quindi proprio un costruttore scritto esattamente con la firma public nomeMadre () {...}, con nomeMadre ovviamente segnaposto) non dovesse esistere, il compilatore ne segnalerà la mancanza, proprio come se noi avessimo voluto scrivere super (parametri) quando il costruttore nomeMadre (parametri) non esiste (errore generico symbolo di compilazione non trovato... .camberman) e farà fallire la compilazione.

2) in qualsiasi blocco di codice della classe figlia (costruttore compreso)
questa seconda modalità permette di accedere a variabili membro e metodi della classe che sta immediatamente prima di questo nella gerarchia (la classe madre/padre, diciamo), ed è indispensabile se si vuole evitare il binding dinamico qualora madre e figlia abbiano un metodo con identica firma e si volesse richiamare il metodo omonimo ma della classe madre (e solo ed esattamente quella!  .huh).

Si usa molto banalmente come:
super.attributo per indicare una variabile membro (che, però, abbia modificatore di accesso almeno protected  .sisi, private non è sufficiente  .nono)
oppure
super.metodo (...) per indicare l'invocazione di "metodo" presente esattamente nella classe madre (qualora ci fosse il problema di omonimia e non si volesse usare il binding dinamico).
Se non c'è omonimia, scrivere super è superfluo (cioè non necessario), però potrebbe essere utile nel caso in cui si pensa che ci sarà la possibilità un giorno che qualche classe figlia (o questa stessa figlia!) avrà un metodo omonimo :-OK.
Nei casi in cui non dovesse esserne richiesta la presenza, io suggerisco a scopo istruttivo di inserirlo comunque.

Buona sera .ciaociao.


Title: Re:Aiuto esercizio
Post by: Luxandro on 14-02-2011, 20:35:32
Esaustivo, come sempre!  :-OK

Grazie mille!  .rido


PS. : Ma ancora non mi entra nella capoccia l'esatto valore del this  :-)|


Title: Re:Aiuto esercizio
Post by: ɹǝǝuıƃuǝsɹǝʌǝɹ on 15-02-2011, 01:11:23
Esaustivo, come sempre!  :-OK
Eh si, le cose vanno fatte bene .sisi.
Almeno io la penso così :boh!
[...] ancora non mi entra nella capoccia l'esatto valore del this  :-)|
Risposta breve: this è una parola chiave che si riferisce all'istanza particolare corrente su cui avviene qualcosa (solitamente una lettura o scrittura) che ha a che fare con lo stato dell'oggetto (ad esempio, ma non solo, quando viene invocato un metodo non static).

Risposta (poco più) lunga:
L'identificatore this ha senso ed esiste in tutti e soli i punti elencati in questo esempio:
Code:
class MiaClasse
{
    //...
    public/private/protected ...tipo... mioMetodo (...) //metodo NON-static!
    {
        //In questo punto del codice
    }

    {
        //in questo altro punto del codice (detto costruttore anonimo, se non lo conoscete, studiatelo!)
    }
   
    //e in questo punto del codice (cioè fra le inizializzazioni inline delle variabili membro NON-static e comunque fuori da qualsiasi blocco di parentesi graffe tranne quelle di "class {...}")
}

Inoltre, se scrivessi in qualche punto del codice il codice:
Code:
MiaClasse mioOggetto = new MiaClasse (...);
//...
mioOggetto.mioMetodo (...);
il nome "this" all'interno del codice di "mioMetodo" verrebbe risolto con la stessa reference in memoria dell'oggetto mioOggetto
(cioè, se si potesse fare, si avrebbe che mioOggetto == this restituisce true).