有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我面临一个困惑

这是我的小代码片段

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

那为什么它显示为空呢

这很令人困惑。有人能解释吗


共 (1) 个答案

  1. # 1 楼答案

    变量在Java中不是多态的。由于您在Son内声明了x,因此此变量实际上与Father中的变量不同。因此,在Soninit方法中,您正在初始化Sonx,而不是Fatherx

    另一方面,您的语句System.out.println(this.x);位于Father类内,因此它只知道Fatherx。由于重写init方法而不再初始化此变量,因此Father中的x仍然是null(默认值),因此它将打印null

    您可以通过从Son类中删除public String x;来解决此问题。这将使Fatherx成为唯一的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
    }