我面临一个混乱。
这是我的小代码段
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();
}
因此,当我创建继承自Class Father的Son的类实例时,JVM会自动调用父亲的类构造函数。当父亲的构造函数调用否则会初始化父亲的字段时,它将创建Son类型的实例。到目前为止好..!
如您所见,字段
x
从父亲的班级派生到儿子的班级。我的代码使用
x
方法初始化init()
。那么为什么它显示为空。
它非常混乱。有人可以解释吗?
最佳答案
变量在Java中不是多态的。由于您在x
中重新声明了Son
,因此该变量实际上是与x
中的变量不同的Father
。因此,在init
的Son
方法中,您正在初始化Son
的x
,而不是Father
的x
。
另一方面,您的语句System.out.println(this.x);
在Father
类内部,因此它仅了解Father
的x
。由于不再通过覆盖init
方法来初始化此变量,因此x
中的Father
保留为null
(默认值),因此将打印null
。
您可以通过从public String x;
类中删除Son
来解决此问题。这将使Father
的x
成为唯一的x
,从而消除了问题。
但是,通常,您希望将此变量设置为private
而不是public
。您也不应在构造函数中调用非final
方法。 It can only introduce bugs。在这种情况下,初始化它的正确方法是在Father
中使用带有参数的构造函数:
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
}
关于java - 父项和子项字段如何在继承中初始化?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54743800/