子类中将超类字段存储在哪里?

时间:2019-12-26 02:10:52

标签: java

我们有以下代码:

class Parent {
    public int i = 5;
}

class Son extends Parent {

}

public class MyTest {

    public static void main(String[] args){
        **Son son = new Son();**
        System.out.println(son.i);

    }

}

执行 Son son = new Son()时,以下与我混淆的问题:

  1. 是否会在内存中创建 Parent 实例?我知道在创建 Son 实例之前,将不带任何参数调用 Parent 默认构造函数,是否正确调用Constructor和create实例是不同的事情?
  2. 如果未创建 Parent 实例,但是 i 字段存储在 Son 实例中的什么位置?因为我们可以通过 son 参考获得 i 的价值?

非常感谢!

3 个答案:

答案 0 :(得分:2)

  

是否在内存中创建Parent实例?我知道在创建Son实例之前,将不带任何参数调用父级默认构造函数,是正确调用构造函数和创建实例是不同的事情吗?

将不会创建Parent的实例,并且确实会调用Parent的构造函数。构造函数只是JVM在创建实例时运行的特殊代码块。没有规则说:“当创建T的实例时,只能运行T的构造函数。”

  

如果未创建Parent实例,但是我在Son实例中存储的字段在哪里?因为我们可以通过儿子参考获得i的值?

仅仅是因为它不是用源代码编写的,并不意味着它不存在。通过编写Son extends Parent,您可以告诉编译器和运行时Son确实有一个名为i的字段,因此您不必在{ {1}}。这是继承的主要目的之一-减少重复代码。

答案 1 :(得分:0)

创建子类的实例时,必须调用超类构造函数以初始化超类字段,在本例中为son.i。如果没有为超类提供构造函数,则Java隐式创建一个默认构造函数,等效于以下代码:

public Parent() {}

扩展Parent时,Son的构造函数通过调用Parent的构造函数开始,通过以下代码隐式完成:

public Son() {
    super() // Calls Parent()
}

简而言之,是的。子类确实会为内存中的超类生成字段。可以将子类视为具有几分风吹草动的父类。例如:

Parent myObj = new Son();
System.out.println(myObj.i); // Still prints 5 because i is still a variable of son

答案 2 :(得分:0)

问题1:是的,如果尚未创建默认的Parent构造函数,则Java将自动创建一个默认的Parent构造函数,并且每次创建新的Son对象时,也会调用Parent构造函数。通过在Son构造函数的第一行中调用super(...),可以显式调用您选择的Parent构造函数(假设您已定义一个或多个)。

问题2:“ i”字段是Parent类的一部分。目前,Son类和所有想要更改它的人都可以使用它的编写方式(可以公共访问)。

进一步的评论:将字段设为类的私有字段(如果可能的话)是最终的,这是一种良好的编程习惯。