"在子类的实例化过程中,超类的私有字段是否也在堆内存中占有一席之地?



考虑一个超类 A 和一个派生类 B,而 A 包含一个私有变量x。B 在其构造函数中包含一个显式的 super() 调用作为第一个参数,而 B 可能还有其他一些变量,如yz。据我所知,私有领域没有继承权。这是否意味着私有字段在执行时不会被实例化:

B b = new b(); 

我的问题是:运行上述代码后堆是什么样子的?当然会有yz,但在这种情况下x呢?

字段继承和字段可见性是两个不同的概念,不要混淆。

字段继承

在某种程度上(为了简化一点),类是制作对象的模板。因此,如果一个类A声明两个字段f1f2,则实例化A将创建具有这两个字段的对象(并在堆上为它们分配内存)。

子类也是用于创建对象的模板,但此模板表示为对另一个类的添加。因此,如果类B声明字段f3并扩展A,它基本上是说,"获取A定义的所有字段,并添加f3"。因此,实例化B会产生一个具有三个字段的对象f1f2f3

现场可见性

字段可见性,通过访问修饰符(如privatepublic)表示,是一种控制代码的哪一部分"看到"(或可以引用)某个字段的方法。private修饰符意味着声明字段的类之外的任何代码都不能引用此字段。但是,这并不意味着该字段不再存在。为了做一个狡猾的类比,如果你和另一个人在一个房间里,你关掉灯,你看不到另一个人,但他们仍然在那里。

为了强调概念是分开的一点,请考虑在某些情况下,您可以看到继承的字段(例如,因为它们是非私有的,但位于不在同一类层次结构中的类中)。在某些情况下,您无法看到继承的字段,例如超类中的私有字段。

当语句执行此操作时,将实例化超类中定义的私有字段。
在这一点上,您操作子类的事实不会改变任何内容。 该字段始终存在且可实例化,只是子类不能直接访问它。
如果超类的字段不可实例化,Java 继承将没有任何意义,因为子类将不一致甚至无法使用,因为超类方法将不再起作用。

例如:

private int x;
A(){
this.x = getIntValue();
}
int getX(){return x;}

和 B 子类:

B(int x){
super(); // in the compiled code even if not in the source code
}

new B().getX()当然会返回超类中实例化的 x 的值。

最新更新