什么是输出?怎么样?

时间:2015-02-25 17:10:49

标签: java

class B{
  B(){
    f();
  }
  public void f(){
    System.out.println("B ctor");
  }
}

class A extends B{
  A(){
    f();
  }

  @Override    
  public void f(){
    System.out.println("A ctor");
  }

  public static void main(String[] args) {
    A a = new A();
    a.f();
    B b = new B();
    b.f();
  }
}

上述程序的输出是

A ctor
A ctor
A ctor
B ctor
B ctor

任何人都可以解释我们是如何获得输出的。

1 个答案:

答案 0 :(得分:1)

让我们尝试通过添加更多打印来可视化发生的事情:

class B{
    B(){
        System.out.println("binit");
        f();
    }
    public void f(){
        System.out.println("B ctor");
    }
}

class A extends B{
    A(){
        System.out.println("ainit");
        f();
    }

    @Override
    public void f(){
        System.out.println("A ctor");
    }

    public static void main(String[] args) {
        System.out.println(1);
        A a = new A();
        System.out.println(2);
        a.f();
        System.out.println(3);
        B b = new B();
        System.out.println(4);
        b.f();
    }
}

我们的输出现在是:

1
binit
A ctor
ainit
A ctor
2
A ctor
3
binit
B ctor
4
B ctor

那么这里发生了什么?在1和2之间我们有两个初始化,即使我们只实例化了A.这是因为子类(A扩展B)默认情况下将调用超类(在本例中为B)构造函数作为实例化的第一件事。 B的构造函数调用f()。但是这个f已被A覆盖,而不是打印" B ctor"将打印" A ctor"。 之后,A的构造函数运行,并打印" A ctor"通过调用他自己的overrode f。

2之后发生的事情非常简单。唯一的区别是,当我们实例化B(在4之后)时,我们不使用覆盖f,而是使用原始覆盖f,因此我们打印" B ctor"。

知道了吗?