Quando le classi interne sono state aggiunte a Java in ver sione 1.1 della lingua sono stati originariamente definiti come una trasformazione in codice compatibile 1.0. Se guardi un esempio di questa trasformazione, penso che renderà molto più chiaro come funzioni effettivamente una classe interiore.
Si consideri il codice dalla risposta Ian Roberts':
public class Foo {
int val;
public Foo(int v) { val = v; }
class Bar {
public void printVal() {
System.out.println(val);
}
}
public Bar createBar() {
return new Bar();
}
}
Quando trasformato in 1.0 codice compatibile, che classe interna Bar
sarebbe diventato qualcosa di simile:
class Foo$Bar {
private Foo this$0;
Foo$Bar(Foo outerThis) {
this.this$0 = outerThis;
}
public void printVal() {
System.out.println(this$0.val);
}
}
Il nome della classe interna è prefissato con il nome della classe esterna in modo da renderlo unico. Viene aggiunto un membro privato nascosto this$0
che contiene una copia esterna this
. E viene creato un costruttore nascosto per inizializzare quel membro.
E se si guarda il metodo createBar
, sarebbe essere trasformato in qualcosa di simile:
public Foo$Bar createBar() {
return new Foo$Bar(this);
}
Quindi vediamo cosa succede quando si esegue il seguente codice.
Foo f = new Foo(5);
Foo.Bar b = f.createBar();
b.printVal();
Innanzitutto istanziare Foo
e intialise l'organo val
a 5 (cioè f.val = 5
).
Successivo chiamiamo f.createBar()
, che istanzia un'istanza di Foo$Bar
e inizializza l'elemento this$0
al valore di this
passato dalla createBar
(cioè b.this$0 = f
).
Infine chiamiamo b.printVal()
che cerca di stampare b.this$0.val
che è f.val
quali è 5.
Ora che era un'esemplificazione regolare di una classe interna. Diamo un'occhiata a cosa succede quando si instilla l'Bar
dall'esterno dello Foo
.
Foo f = new Foo(5);
Foo.Bar b = f.new Bar();
b.printVal();
Applicando nuovamente il nostro 1.0 trasformazione, che la seconda linea sarebbe diventato qualcosa di simile:
Foo$Bar b = new Foo$Bar(f);
Questo è quasi identica alla chiamata f.createBar()
. Di nuovo stiamo istanziando un'istanza di Foo$Bar
e inizializzando il membro this$0
a f. Quindi, di nuovo, b.this$0 = f
.
E di nuovo quando si chiama b.printVal()
, si sta stampando b.thi$0.val
che è f.val
quali è 5.
La cosa fondamentale da ricordare è che la classe interna ha un membro nascosto in possesso di una copia del this
dalla classe esterna. Quando si crea un'istanza di una classe interna all'interno della classe esterna, viene inizializzata implicitamente con il valore corrente di this
. Quando istanziate la classe interna dall'esterno della classe esterna, specificate esplicitamente quale istanza della classe esterna utilizzare, tramite il prefisso sulla parola chiave new
.
Per riferimento, [classe interna] (http://docs.oracle.com/javase /tutorial/java/javaOO/nested.html). –
Inoltre, credevo che 'new' fosse un operatore in molte lingue. (Ho pensato che potresti anche sovraccaricare 'new' in C++?) La classe interna di Java è un po 'strana per me, comunque. –
Non ci sono domande stupide su StackOverflow! –