从超类构造函数调用子类方法

时间:2017-07-19 08:03:04

标签: java inheritance constructor

public class A { 
    String bar = "A.bar";

    A() { foo(); }

   public void foo() {
    System.out.println("A.foo(): bar = " + bar);
   }
 }

public class B extends A {
    String bar = "B.bar";

    B(){ foo(); }

    public void foo(){
        System.out.println("B.foo(): bar = " + bar);
    }
}

public class C {
    public static void main(String[] args){
        A a = new B();
        System.out.println("a.bar = " + a.bar);
        a.foo();
    }
}

为什么第一个输出有bar = null? 是因为B.foo()是在创建B类之前调用​​的吗?如果是,那么怎样才能调用B.foo()? 或者是因为B.foo()中的字段栏试图从A获取bar字段但无法访问它?

我的问题与链接的问题不同,我不是在询问呼叫顺序,我问为什么第一个输出为空?另一个问题不是字段或空变量。

我不明白B.foo中的bar变量如果在A和B中定义它是如何为空。

3 个答案:

答案 0 :(得分:0)

首先我会告诉你, A 类中的变量 bar 其他变量 bar <完全不同/ strong>在班级 B

你可能希望他们是这样的一个变量:

public class B extends A{

public B (){
        bar = "B.bar";´
    foo();
}
void foo(){
    System.out.println("B.foo bar ="+ bar);
}

}

你将获得结果:

B.foo bar =A.bar
B.foo bar =B.bar
a.bar=B.bar
B.foo bar =B.bar

如果没有,请告诉我,我还会为您描述您的特殊情况(为什么 bar = null

答案 1 :(得分:0)

第一次打印B.foo(): bar=null的原因是因为当您调用行A a = new B();时,您正在创建一个类型为B的对象,该对象调用对象的构造函数类型为B。但是,该构造函数对super的构造函数进行了“隐藏”A调用。问题是类B尚未创建(您现在正在创建类A的过程中),因此它们的参数(例如bar)不是初始化,意味着它们被赋予null值。你仍然得到B.foo():,因为动态调度的调用是动态调度,因此调用foo的函数B。只有在调用A的构造函数后,才调用B的构造函数,然后初始化B的变量 - 包括bar

答案 2 :(得分:0)

您好,这是您的代码逐行运行 enter image description here