Objeto de clase interna

Sep 19 2020

No pude entender el comportamiento del siguiente código.

Mi expectativa era que imprimiera 100 en ambos println()métodos. ¿Por qué el resultado es diferente?

Si elimino el comentario del getX()método en la clase interna, entonces la salida de println() métodos es la misma, que es 100.

No pude entender el razonamiento de un comportamiento diferente. Por favor ayúdame a entender.

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

Respuestas

4 Turing85 Sep 19 2020 at 05:26

Desde MyInnerla perspectiva de ', hay dos private int xcampos en juego aquí:

  • Un campo super.xque es heredado MyOuter, pero inaccesible porque está declarado como privatey MyInnercomo un objeto heredado no puede acceder a este campo.
  • Un campo MyOuter.this.xde la sorrounding MyOuter -instance (ya que MyInneres un no-estática) clase interna (, siempre está unido a una instancia de la rodea MyOuter), que es accesible.

El método setX()en MyInnerno puede acceder al campo heredado super.x, por lo que accede al campo MyOuter.this.xy establece sus valores en 100. Una llamada consecutiva en los alrededores MyOuters' getX()volverá 100.

La llamada innerObj.getX()(que se hereda MyOutery puede acceder super.x) devuelve el valor del campo heredado super.x(que aún tiene su valor inicial de 3).

Si eliminamos el extends MyOuterde e incluimos el getX()método-en MyInner, el código se comporta como se esperaba.


El hecho de que MyInnerno pueda acceder al campo heredado private xes confuso al principio, pero el comportamiento en realidad está en línea con el comportamiento de la palabra clave protecteden el contexto de métodos estáticos en clases heredadas, como se discutió en esta publicación de Hariharan.