Inneres Klassenobjekt

Sep 19 2020

Ich konnte das Verhalten des folgenden Codes nicht verstehen.

Meine Erwartung war, dass es 100 in beiden println()Methoden drucken sollte . Warum ist das Ergebnis anders?

Wenn ich die getX()Methode in der inneren Klasse auskommentiere , ist die Ausgabe von println() Methoden dieselbe, nämlich 100.

Ich konnte die Gründe für ein anderes Verhalten nicht herausfinden. Bitte helfen Sie mir zu verstehen.

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; }
    }
}

Antworten

4 Turing85 Sep 19 2020 at 05:26

Aus MyInnerder Sicht gibt es hier zwei private int xFelder:

  • Ein Feld super.x, von dem geerbt wird MyOuter, auf das jedoch nicht zugegriffen werden kann , weil es als privateund MyInnerals geerbtes Objekt deklariert ist , kann nicht auf dieses Feld zugreifen.
  • Ein Feld MyOuter.this.xaus der Sorrounding- MyOuter Instanz (da MyInneres sich um eine (nicht statische) innere Klasse handelt, ist es immer an eine Instanz der Umgebung gebunden MyOuter), auf die zugegriffen werden kann .

Die Methode setX()in MyInnerkann nicht auf das geerbte Feld zugreifen super.x, greift also auf das Feld zu MyOuter.this.xund setzt seine Werte auf 100. Ein konsekutiver Anruf auf dem umliegenden MyOuter‚s getX()zurückkehren wird 100.

Der Aufruf innerObj.getX()(der von geerbt wird MyOuterund auf den super.xzugegriffen werden kann ) gibt den Wert des geerbten Feldes zurück super.x(der noch den Anfangswert von hat 3).

Wenn wir extends MyOuterdie getX()Methode von entfernen und in einschließen MyInner, verhält sich der Code wie erwartet.


Die Tatsache, dass MyInnernicht auf das geerbte Feld zugegriffen werden kann, private xist zunächst verwirrend, aber das Verhalten protectedstimmt tatsächlich mit dem Verhalten des Schlüsselworts im Kontext statischer Methoden beim Erben von Klassen überein, wie in diesem Beitrag von Hariharan erläutert