GGAbramoF55 ha scritto:
So creare un array di oggetti di una classe (nel mio caso la classe "Studente"), ma non un array di oggetti di una classe interna (nel mio caso "Indirizzo").
Per favore, mi date una mano? Mi dite come devo scrivere il codice?
Tralasciando per un momento il fatto che
non hai seguito le convenzioni standard per i metodi "accessori" (
setter/
getter), dovresti comprendere meglio le classi dette genericamente "innestate".
Le classi "innestate" si dividono in due tipi:
- le "nested" (static) class
- le "inner" (non static!) class che sono di 3 tipi: le "regular" (insomma, regolari, come la tua Indirizzo), le "anonymous" e le "method local" (o semplicemente "local").
Le nested class sono classi interne marcate static. Non hanno alcuna peculiarità davvero particolare, se non per il fatto che la classe "contenitore" fa sostanzialmente solo da namespace in più per la nested class.
Le inner class (non static) invece sono più particolari, perché esiste una relazione molto specifica tra la istanza della inner class e la istanza della classe che la contiene.
Arriviamo al dunque:
per ottenere nel tuo caso un oggetto Indirizzo, DEVI prima creare un oggetto Studente e su questo istanziare il Indirizzo.
Questo è il punto essenziale per quella relazione particolare detta poco fa. In virtù di questa relazione, dall'interno della classe inner è possibile accedere ai dati della classe contenitore, semplicemente perché la inner class mantiene il riferimento ad una istanza specifica della classe contenitore.
La tua classe Indirizzo non "eredita" un bel nulla da Studente. Non nel senso della ereditarietà tradizionale. Semplicemente 1 oggetto Indirizzo deve essere legato ad 1 oggetto Studente. E dall'interno di Indirizzo è lecito accedere a metodi e campi "di istanza" di quell'oggetto Studente associato.
Questo di seguito l'ho scritto al volo ma farà sicuramente (spero) capire:
public class Prova {
public static void main(String[] args) {
Persona mario = new Persona();
mario.setNome("Mario");
Persona.Hobby hobby1 = mario.new Hobby();
hobby1.setDescrizione("suonare il pianoforte");
System.out.println(hobby1);
}
}
class Persona {
private String nome;
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
class Hobby {
private String descrizione;
public String getDescrizione() {
return descrizione;
}
public void setDescrizione(String descrizione) {
this.descrizione = descrizione;
}
public String toString() {
return getDescrizione() + " è l'hobby di " + getNome();
}
}
}
Ho creato un oggetto Persona di nome Mario e l'ho assegnato ad una variabile appunto
mario.
Vedi sotto la forma
mario.new Hobby() ?
Questa è una invocazione di new molto particolare, in pratica si invoca il new della inner class su una istanza specifica della classe contenitore.
Il System.out.println(hobby1) fa invocare il toString() di Hobby e la stampa è
suonare il pianoforte è l'hobby di Mario
Nota che nel toString() ho invocato getNome(). In virtù della relazione molto speciale detta prima, da un metodo di istanza di Hobby è lecito usare campi/metodi di istanza di Persona, perché i due oggetti sono collegati (l'oggetto Hobby mantiene un riferimento nascosto all'oggetto Persona).
Ma nota che se si tentasse di fare:
System.out.println(hobby1.getNome()); // ERRORE!!
Sarebbe un errore. La classe Hobby non "eredita" un bel nulla da Persona e quindi su un reference di tipo Hobby NON puoi invocare metodi di Persona.
Tutto questo ti risulta più chiaro ora?
EDIT:
GGAbramoF55 ha scritto:
Ho trovato questo esempio cercando sul Web:
archivioAlunniIstitutoScolastico[i] = new Studente.Indirizzo();
Riguardo questo, la forma
new ClasseContenitore.ClasseInterna() si riferisce alle "nested" (static) class. NON alle "inner" class.