作为一个扭转脑子的例子,我的一位教授给了我们以下练习,以了解继承。我们必须弄清楚输出。
//java
public class A {
public void f() {
System.out.println("A -> f()");
x = x + 4;
if (x < 15) this.f(); //the f-call
}
public int x = 5;
}
public class B extends A {
@Override
public void f() {
System.out.println("B -> f()");
x = x + 3;
super.f();
}
}
public class Main {
public static void
main(String[] args) {
A a = new B();
System.out.println("a.f()");
a.f();
System.out.println(a.x);
}
}
正如我预期的那样,输出
然而,我现在想知道。有没有办法让A中的 f-call 调用A中的f方法,即使我在B对象中使用它,类似于我在B中使用A调用f的方式super.f()。所以输出会变成(我认为):
这可能吗?如果是这样,怎么样?
注意:我不确定这个实际应用是什么,我只是想学习一些新东西:P
答案 0 :(得分:5)
简短的回答是“不”你不能这样做。
更长的答案是允许这会破坏对继承的各种保证。你的B班基本上说“我现在提供public void f()
的规范方法”。因为B
正在提供所述方法,所以允许回调父母使用它(以及这是非常有用的事情)。
如果A
被允许这样做,那么它基本上会绕过B
想要覆盖的行为。
有多种模式可以为您提供类似的行为,例如the Template Pattern
答案 1 :(得分:2)
因为多态将适用于超类对象的所有方法,所以被调用的f
将始终是对象的运行时类型 - 在这种情况下,B
,所以始终会调用B
&#39; f
方法。这在Java中无法改变。
您可以通过A
方法f
方法开展private
foo
方法的工作来解决这个问题,例如f
,所以调用foo
时,会重复调用A
。在public void f()
{
foo();
}
private void foo() {
System.out.println("A -> f()"); // Lie.
x = x + 4;
if (x < 15) this.foo(); //the "f"-call
}
:
{{1}}