【问题标题】:java covariant return typejava协变返回类型
【发布时间】:2011-09-02 11:47:52
【问题描述】:

为什么下面的代码打印“1”?

class A {
    int x = 1;
}

class B extends A {
    int x = 2;
}

class Base {

    A getObject() {
        System.out.println("Base");
        return new B();
    }
}

public class CovariantReturn extends Base {

B getObject() {
   System.out.println("CovariantReturn");
   return new B(); 
}
/**
 * @param args
 */
public static void main(String[] args) {
    Base test = new CovariantReturn();
    System.out.println(test.getObject() instanceof B);
    System.out.println(test.getObject().x);
}
}

【问题讨论】:

    标签: java return covariant


    【解决方案1】:

    因为您指的是不受多态性影响的字段。如果您改为使用getX(),它将返回2

    您要问的是,A 类中定义的字段x 的值(因为Base.getObject() 返回A)。即使CovariantReturn 覆盖了返回B 的方法,您也不会将您的对象称为CovariantReturn

    稍微扩展一下字段如何不受多态性影响 - 字段访问是在编译时实现的,因此无论编译器看到什么,这就是访问的内容。在您的情况下,该方法定义为返回A,因此可以访问A.x。另一方面,方法是根据运行时类型调用的。所以即使你定义返回A但返回一个B的实例,你调用的方法也会在B上调用。

    【讨论】:

    • 但是方法定义返回A。所以A.x是被访问的。
    • @kris 您正在使用A 的引用调用方法,因为它具有返回类型A
    • 好的,所以即使 test.getObject() 返回 B 的实例,测试变量仍然是 Base 引用,因此如果我打印 x 它调用 Base:getObject() ?
    • test.getObject() instanceof B 返回 true - 这让我很困惑!
    • 因为instanceof 检查发生在运行时。 A.x 在编译时实现。
    【解决方案2】:

    @kris979 虽然您返回的是 B,但我认为不同之处在于返回类型是 A。因此打印了 A 中 x 的值,即 1。

    【讨论】:

      【解决方案3】:

      正如 Bozho 所指出的 - 实例变量永远不会受到多态性的影响。让我给你一个简单的小例子。

      class Base {
          int i = 1;
          void method() {
              System.out.println("in base");
          }
      }
      
      class Sub extends Base {
          int i = 2;
      
          void method() {
              System.out.println("in sub");
          }
      }
      
      public class Test { 
          public static void main(String[] args) {
              Base obj = new Sub();
              obj.method();
              System.out.println(obj.i);
          }
      }
      

      此代码将打印 - 在 sub 和 1

      【讨论】:

      • 不错。简单明了的答案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-24
      • 1970-01-01
      • 1970-01-01
      • 2020-06-14
      • 1970-01-01
      相关资源
      最近更新 更多