34
class A {
   boolean f(A a) { return true; }
}
class B extends A {
   boolean f(A a) { return false; } // override A.f(A)
   boolean f(B b) { return true; }  // overload A.f
}

void f() {  
   A a = new A();
   A ab = new B();
   B b = new B();
   ab.f(a); ab.f(ab); ab.f(b); //(1) false, false, *false*
   b.f(a); b.f(ab); b.f(b);    //(2) false, false, true
}

你能解释一下第一行最后一个错误的输出,为什么它不是真的?

4

4 回答 4

60

你能解释一下第一行最后一个错误的输出,为什么它不是真的?

的编译时类型abA,因此编译器(执行重载解析)确定唯一有效的方法签名是f(A a),所以它调用它。

执行时,该方法签名被执行为B.f(A a)因为B覆盖它。

永远记住,签名是在编译时选择的(重载),但实现是在执行时选择的(覆盖)。

于 2012-07-24T06:12:03.950 回答
1

嗯..因为你调用的是 A 的类型。所以你只能调用 f(A a) 的版本。在 B 中返回 false。

于 2012-07-24T06:13:18.877 回答
1

由于您使用的是 A 的对象类型,因此您只能调用 f(AA)。因为 B 覆盖它。

于 2012-07-24T06:14:53.573 回答
0

你能解释一下第一行最后一个错误的输出,为什么它不是真的?

否则认为:-

尝试在 B 类下面评论(覆盖代码)

boolean f(A a) { return false; } // override A.f(A)

并在此方法中在 A 类中添加 syso -->boolean f(A a){....}

然后你会看到,ab.f(A a)或者ab.f(B b)只会调用f(A a)A 类的方法。

因为 ab 是 A 型。

另请注意 - 您也无法从对象 ab 调用 B 类的任何方法。

希望这能进一步澄清上述精彩答案。

最后,您现在可能会寻求这个 -->为什么我们在 Java 中为子对象分配父引用?

于 2017-05-04T08:12:34.160 回答