Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 什么是超级();在子类中工作?_Java - Fatal编程技术网

Java 什么是超级();在子类中工作?

Java 什么是超级();在子类中工作?,java,Java,我觉得超级,;意思几乎和我们称之为超类构造函数一样,但它不是 class A { A() { foo(); } void foo() { System.out.print("A"); } } class B extends A { void foo() { System.out.print("B"); } B() { super(); super.fo

我觉得超级,;意思几乎和我们称之为超类构造函数一样,但它不是

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

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


}

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

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

当我呼唤新的B;为什么?我正在调试它,并且超级调用了A的构造函数,但是它打印出了B这是我不理解的,为什么在这个super.foo之后会打印出A呢。有人能解释一下它是如何工作的吗?

它打印BA的原因:

你叫新的B

构造函数调用一个构造函数作为超级调用 构造函数调用foo foo在B中被重写,因此它解析为B.foo 富普林斯酒店 B.foo返回,构造函数返回 构造函数移动到下一个调用,即super.foo 由于超级资格赛的缘故,这决定了A.foo A.foo打印一个 结局


为什么从A打给foo的电话中打印B?因为foo是一个实例方法,这是B的一个实例,并且B有一个与a.foo具有相同签名的方法,所以这将解析为子类方法B.foo。这称为虚拟方法解析,是面向对象编程的一个基本概念。术语是B.foo覆盖A.foo。

您的程序流程如下所示:

调用B的构造函数。 它使用super;调用A的构造函数;。另一方面,这一行是不必要的,如果忽略,将自动完成。 A的构造函数调用B的foo;是到foo的B版本,因为对象是B的实例,而foo的B版本覆盖了foo的A版本。所以你得到了一个“B”字。 A的构造函数返回到B的构造函数,后者调用super.foo;。这将调用foo的A版本,因为您特别告诉它使用super前缀。所以它会打印一个“A”。请注意,这不是对构造函数的调用,以防您对此感到困惑。
其中一条评论中的引用对此做了更多解释。

我不认为标记的问题实际上是重复的-OP的问题实际上与super无关,而是关于基类的虚拟调用。我不认为重复的问题直接回答了您的确切问题,但既然这已经结束了:我想,为了直观地理解为什么在调用super时调用B的foo,最好将A设为抽象类,将foo设为抽象方法。现在,要调用哪个方法是非常清楚的,因为A的foo是抽象的。您重写了foo。我相信A中的构造函数调用了B中被重写的版本。然后,它调用super版本的foo,打印出A。如果我错了,请纠正我。你能对这个虚拟调用给出更好的解释吗,这样我就不了解它是如何工作的了@OliverCharlesworth@PiotrKedra谢谢你的anserw,链接也很有用谢谢,它解释了我一点