Oggetto della classe interna
Non sono riuscito a capire il comportamento del codice seguente.
La mia aspettativa era che dovesse stampare 100 in entrambi i println()metodi. Perché il risultato è diverso?
Se rimuovo il commento getX()nella classe interna, l'output di println() metodi è lo stesso che è 100.
Non riuscivo a capire il ragionamento di un comportamento diverso. Per favore aiutami a capire.
public class Foo {
public static void main(String[] args) {
MyOuter outerObj = new MyOuter();
MyOuter.MyInner innerObj = outerObj.new MyInner();
innerObj.setX();
System.out.println("x: " + innerObj.getX()); //x: 3
System.out.println("x: " + outerObj.getX()); //x: 100
}
}
class MyOuter {
private int x = 3;
public int getX() { return x; }
class MyInner extends MyOuter {
public void setX(){ x = 100; }
// public int getX() { return x; }
}
}
Risposte
Dal MyInnerpunto di vista di, ci sono due private int xcampi in gioco qui:
- Un campo
super.xereditato daMyOuter, ma inaccessibile perché dichiarato comeprivateeMyInnercome oggetto che eredita non può accedere a questo campo. - Un campo
MyOuter.this.xdal circostanteMyOuter-instance (poichéMyInnerè un non-statico) classe interna (, è sempre limitata al caso del circostanteMyOuter), che è accessibile.
Il metodo setX()in MyInnernon può accedere al campo ereditato super.x, quindi accede al campo MyOuter.this.xe imposta i suoi valori su 100. Una chiamata consecutiva sulle circostanti MyOuters' getX()tornerà 100.
La chiamata innerObj.getX()(che è ereditata da MyOutere può accedere super.x) restituisce il valore del campo ereditato super.x(che ha ancora il suo valore iniziale di 3).
Se rimuoviamo extends MyOuterda e includiamo il getX()-metodo in MyInner, il codice si comporta come previsto.
Il fatto che MyInnernon possa accedere al campo ereditato private xè inizialmente protectedfonte di confusione, ma il comportamento è in realtà in linea con il comportamento della parola chiave nel contesto dei metodi statici nelle classi ereditate come discusso in questo post di Hariharan