Objet de classe interne

Sep 19 2020

Je ne pouvais pas comprendre le comportement du code ci-dessous.

Je m'attendais à ce qu'il imprime 100 dans les deux println()méthodes. Pourquoi le résultat est-il différent?

Si je décommente la getX()méthode dans la classe interne, la sortie de println() méthodes est la même, à savoir 100.

Je ne pouvais pas comprendre le raisonnement d'un comportement différent. S'il vous plaît, aidez-moi à comprendre.

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

Réponses

4 Turing85 Sep 19 2020 at 05:26

Du MyInnerpoint de vue de S, il y a deux private int xdomaines en jeu ici:

  • Un champ super.xhérité de MyOuter, mais inaccessible car déclaré en tant que privateet en MyInnertant qu'objet héritant ne peut pas accéder à ce champ.
  • Un champ MyOuter.this.xde la sorrounding MyOuter -instance (depuis MyInnerun (non statique) classe interne, il est toujours lié à une instance de l'entourage MyOuter), qui est accessible.

La méthode setX()dans MyInnerne peut pas accéder au champ hérité super.x, elle accède donc au champ MyOuter.this.xet définit ses valeurs sur 100. Un appel consécutif sur les alentours MyOuter« s getX()retournera 100.

L'appel innerObj.getX()(qui est hérité de MyOuteret auquel il est possible d'accéder super.x) retourne la valeur du champ hérité super.x(ayant toujours sa valeur initiale de 3).

Si nous supprimons le extends MyOuterfrom et incluons la getX()méthode dans MyInner, le code se comporte comme prévu.


Le fait de MyInnerne pas pouvoir accéder au champ hérité private xest déroutant au début, mais le comportement est en fait conforme au comportement du mot-clé protecteddans le contexte des méthodes statiques dans l'héritage de classes comme discuté dans cet article par Hariharan