我们有以下代码:
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()时,以下与我混淆的问题:
非常感谢!
答案 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类和所有想要更改它的人都可以使用它的编写方式(可以公共访问)。
进一步的评论:将字段设为类的私有字段(如果可能的话)是最终的,这是一种良好的编程习惯。