父项和子项字段如何在继承中初始化?

时间:2019-02-18 09:13:00

标签: 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";
    }

    @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()

然后为什么它显示为空。

非常混乱。有人可以解释吗?

1 个答案:

答案 0 :(得分:1)

变量在Java中不是多态的。由于您在x中重新声明了Son,因此该变量实际上将是与x中的变量不同的 Father。因此,在init的{​​{1}}方法中,您正在初始化Son的{​​{1}},但不是 Sonx

另一方面,您的语句Fatherx类内部,因此它只知道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