Java通过受保护的getter访问私有超类成员

时间:2016-02-11 20:15:52

标签: java class oop inheritance access-modifiers

我知道在Java中,只要超类提供公共或受保护的getter方法,就可以访问子类中超类的私有成员。我也知道子类实际上并没有继承私有成员。考虑以下情况......

Class A {
    private var = 2;
    protected int getVar(){
        return var;
    }
}

Class B extends A{

   public void printVar(){
       System.out.println(getVar());
   }
}

Class Main{

    public static void main(args []){

         B b= new B();
         b.printVar();
    }
}

我想理解,因为我们正在创建子类B的实例,该私有成员分配给内存的确切时间和时间是什么,它的范围是什么?它是如何存在的,因为实际上从未创建过A的实例?它不是静态变量,或者最终是堆栈动态还是隐式堆动态?我认为当你从超类中实例化一个子类时,你继承了不是私有的成员和方法,然后那些被实例化为子类的对象实例的一部分(除非它们被重写)等),因此只有一个对象被分配为堆动态变量。但是如果这些私有成员没有被继承,那么编译器只是在调用继承的getter方法时才提供堆栈动态引用,并且仅在这种情况下?

2 个答案:

答案 0 :(得分:3)

您认为超类的私有成员不是由子类继承的假设是错误的。所有成员都是继承的。子类的私有成员是子类实例的一部分,但是不能通过子类的代码直接访问它们。

在超类中使用受保护的getter返回私有成员的值,为子类提供了访问私有成员的值的方法(虽然它不能修改它,除非你也有受保护的或超级班的公共二传手)。

答案 1 :(得分:2)

  

但我也知道子类实际上并没有继承私有成员。

是的。 B 的实例A的实例,它包含所有相同的字段。你不能再直接访问私人领域,但它们仍然存在。

  

它是如何存在的,因为实际上从未创建过A的实例?

创建B时,也会调用A中的构造函数,这样可确保B实例已正确初始化为有效A。不要将子类视为与它的超类不同的东西。 B仍为A;它只是做得更多。