什么是super();在子类工作?

时间:2018-01-30 19:46:18

标签: java

我认为super();与我们称之为超类构造函数几乎相同,但它没有。

class A {
    A() {
        foo();
    }

    void foo() {
        System.out.print("A");
    }


}

class B extends A {
    void foo() {
        System.out.print("B");
    }

    B() {
        super();
        super.foo();
    }
}

当我致电new B();时,会打印BA为什么?我正在调整它并super()调用A的构造函数,但它打印B(这是我不理解的),以及为什么在此super.foo()打印A之后正如它应该。有人可以解释它是如何工作的吗?

2 个答案:

答案 0 :(得分:1)

打印BA的原因:

你叫新B();

  1. B构造函数调用构造函数(您的super()调用)
  2. 构造函数调用foo
  3. foo()在B中被覆盖,因此它解析为B.foo()
  4. B.foo()prings" B"
  5. B.foo()返回,A构造函数返回
  6. B构造函数移动到下一个调用,即super.foo()
  7. 因为" super"资格,这转发给A.foo()
  8. A.foo()打印" A"
  9. 结束

    为什么打印" B"从A的调用foo()?因为foo()是一个实例方法,"这个"是B的实例,B有一个与A.foo具有相同签名的方法,因此这解析为子类方法B.foo。这称为虚方法解析,是面向对象编程的基本概念。术语是B.foo覆盖A.foo。

答案 1 :(得分:0)

您的计划流程如下:

  1. 调用B的构造函数。
  2. 使用super();调用A的构造函数。顺便说一句,该行是不必要的,如果遗漏,将自动完成。
  3. A的构造函数调用B的foo()。调用foo();是foo()的B版本,因为该对象是B的实例,而Boo版本的foo()覆盖了A foo()的版本。所以你得到一个' B'打印。
  4. A的构造函数返回B的构造函数,调用super.foo();。这称为foo()的A版本,因为你特意告诉它使用" super"字首。所以它打印了一个' A'。 (请注意,这不是对构造函数的调用,以防您对此感到困惑。)
  5. 其中一条评论(What is virtual method calling in java?)中的引用更多地解释了这一点。