我知道在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方法时才提供堆栈动态引用,并且仅在这种情况下?
答案 0 :(得分:3)
您认为超类的私有成员不是由子类继承的假设是错误的。所有成员都是继承的。子类的私有成员是子类实例的一部分,但是不能通过子类的代码直接访问它们。
在超类中使用受保护的getter返回私有成员的值,为子类提供了访问私有成员的值的方法(虽然它不能修改它,除非你也有受保护的或超级班的公共二传手)。
答案 1 :(得分:2)
但我也知道子类实际上并没有继承私有成员。
是的。 B
的实例是A
的实例,它包含所有相同的字段。你不能再直接访问私人领域,但它们仍然存在。
它是如何存在的,因为实际上从未创建过A的实例?
创建B
时,也会调用A
中的构造函数,这样可确保B
实例已正确初始化为有效A
。不要将子类视为与它的超类不同的东西。 B
仍为A
;它只是做得更多。