Java 如何在继承中初始化父字段和子字段?
我面临一个困惑 这是我的小代码片段Java 如何在继承中初始化父字段和子字段?,java,inheritance,Java,Inheritance,我面临一个困惑 这是我的小代码片段 public class Father { public String x; public Father() { this.init(); System.out.println(this); System.out.println(this.x); } protected void init() { x = "Father"; } @Overr
public class Father {
public String x;
public Father() {
this.init();
System.out.println(this);
System.out.println(this.x);
}
protected void init() {
x = "Father";
}
@Override
public String toString() {
return "I'm Father";
}
void ParentclassMethod(){
System.out.println("Parent Class");
}
}
public class Son extends Father {
public String x;
@Override
protected void init() {
System.out.println("Init Called");
x = "Son";
}
@Override
public String toString() {
return "I'm Son";
}
@Override
void ParentclassMethod(){
super.ParentclassMethod();
System.out.println("Child Class");
}
}
public class MainCLass{
public static void main(String[] args){
Son ob = new Son();
}
所以,当我创建从类父继承的子类实例时,JVM会自动调用父类构造函数。当父的构造函数调用否则父的字段不会初始化时,它会创建子类型实例。到目前为止还不错
如您所见,字段x
是从父类派生到子类的。
我的代码使用init()
方法初始化x
那为什么它显示为空呢
这很令人困惑。有人能解释吗?变量在Java中不是多态的。由于您在
Son
中重新声明了x
,因此该变量实际上与Father
中的变量不同。因此,在子的init
方法中,您正在初始化子的x
,而不是父的x
另一方面,您的语句System.out.println(this.x)
在父类中,因此它只知道父类的x
。由于重写init
方法而不再初始化此变量,因此Father
中的x
将保持null
(默认值),因此它将打印null
您可以通过删除公共字符串x从Son
类中选择code>。这将使父亲的x
成为唯一的x
,从而消除问题
但是,一般情况下,您希望将此变量设置为private
,而不是public
。您也不应该在构造函数中调用非final
方法。在这种情况下,初始化它的正确方法是在父类中有一个带参数的构造函数
:
public class Father {
private String x;
protected Father(String x) {
this.x = x;
System.out.println(this);
System.out.println(this.x);
}
public Father() {
this("Father");
}
// Rest of father's code, without the init method
}
public class Son extends Father {
public Son() {
super("Son");
}
// Rest of son's code, without the init method
}
不要从构造函数中调用可重写的方法。请尝试从Son类中删除字符串x
,并在Son的init()
中调用super.x=“Son”
,字段不是固有的,只有实例方法