我正面临一个困惑。
这是我的小代码段
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();
}
因此,当我创建从父类继承的Son的类实例时,JVM会自动调用父类的构造函数。当父亲的构造函数调用否则会初始化父亲的字段时,它将创建Son类型的实例。到目前为止很好..!
如您所见,字段x
是从父级继承到父级。
然后我的代码使用x
方法初始化init()
。
然后为什么它显示为空。
非常混乱。有人可以解释吗?
答案 0 :(得分:1)
变量在Java中不是多态的。由于您在x
中重新声明了Son
,因此该变量实际上将是与x
中的变量不同的 Father
。因此,在init
的{{1}}方法中,您正在初始化Son
的{{1}},但不是 Son
的x
。
另一方面,您的语句Father
在x
类内部,因此它只知道System.out.println(this.x);
的{{1}}。由于您不再通过覆盖Father
方法来初始化此变量,因此Father
中的x
仍为init
(默认值),因此它将打印x
您可以通过从Father
类中删除null
来解决问题。这将使null
的{{1}}成为唯一的public String x;
,从而消除了问题。
但是,通常,您希望将此变量设为Son
而不是Father
。您也不应在构造函数中调用非x
方法。 It can only introduce bugs。在这种情况下,初始化它的正确方法是在x
中使用带有参数的构造函数:
private