Java 中的协方差和重载


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
}

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

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

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

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

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

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

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

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

不这么想:-

尝试在下面的 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)将仅调用类 A f(A a)方法。

由于 ab 属于 A 型。

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

希望这进一步为上述精彩答案增添更多澄清。

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

相关内容

  • 没有找到相关文章

最新更新