【问题标题】:calling a subclass method from superclass constructor从超类构造函数调用子类方法
【发布时间】:2017-07-19 08:03:04
【问题描述】:
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 之前调用了 B.foo() 吗?如果是,那么 B.foo() 怎么会被调用? 还是因为 B.foo() 中的 bar 字段试图从 A 获取 bar 字段但无法访问?

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

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

【问题讨论】:

标签: java inheritance constructor


【解决方案1】:

首先我要告诉你,A类中的变量barother变量bar 在 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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 好吧,如果 foo 是静态的,我会同意,但事实并非如此,所以我不明白如果没有 B 的实例,它如何调用 foo。
    • @Raz 因为你不初始化方法。该方法属于B 类。动态调度机制尝试调用Afoo,但是当它“看到”对象的动态类型是B 类型时,它只是调用Bfoo 方法。
    • 我试着看看你是否可以在类初始化之前调用一个类的方法。我发现这个问题stackoverflow.com/questions/2394205/… 表明你不能
    • @Raz 可能是因为有一些中间立场 - 变量尚未定义,因为创建B 的实际构造函数的阶段尚未开始,但方法已经可用因为动态调度必然会调用B中的方法
    • 我找到了答案,显然编译器在调用 super() 之后立即移动了所有字段初始化。因此,当调用 B 的构造函数时,首先调用 super() 并在该 bar 被初始化之后 stackoverflow.com/questions/18830103/…
    【解决方案3】:

    您好,这是您的代码逐行运行

    【讨论】:

      猜你喜欢
      • 2016-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-16
      • 2012-12-17
      • 1970-01-01
      相关资源
      最近更新 更多