【问题标题】:Covariance and Overloading in JavaJava中的协方差和重载
【发布时间】:2012-07-24 06:06:23
【问题描述】:
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
}

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

【问题讨论】:

  • 我不明白为什么人们会费心发布一个如此简短且不像@JonSkeet 的帖子那样解释性强的答案。
  • 前段时间我也有类似的问题,也许这对你有帮助:stackoverflow.com/questions/3883414/…
  • 请提高您的接受率

标签: java overloading covariance


【解决方案1】:

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

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

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

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

【讨论】:

  • 一看到你的答案,即使没有阅读你的答案,我也删除了我的:)..你的答案不可能不是最好的:)。
  • 看到你的回答后,我们不能停止投票:)
  • 你能解释一下 b.f (ab); ?
  • @nabil:调用B.f(A a) 因为ab 的编译时类型是A
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

      不这样想:-

      尝试在 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 类的任何方法。

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

      最后,你现在可以找这个 --> Why do we assign a parent reference to the child object in Java?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-06
        • 2011-02-09
        • 1970-01-01
        • 1970-01-01
        • 2015-11-22
        相关资源
        最近更新 更多