【问题标题】:java - Overriding with covariant types wrt variablesjava - 用协变类型覆盖变量
【发布时间】:2015-05-04 08:26:49
【问题描述】:
class G {

    int x = 5;
}

class H extends G {

    int x = 6;
}

public class CovariantTest {

    public G getObject() {
        System.out.println("g");
        return new G();
    }

    public static void main(String[] args) {
        CovariantTest c1 = new SubCovariantTest();
        System.out.println(c1.getObject().x);
        System.out.println(new H().x);
    }
}

class SubCovariantTest extends CovariantTest {

    public H getObject() {
        System.out.println("h");
        return new H();
    }
}

输出:

h
5
6

显然 main 方法中的两个 println 语句是不一样的。从类 SubCovariant 的 getObject 方法返回的新 H() 对象如何分配给 G 引用?

【问题讨论】:

  • 你发布的代码永远不会得到 5 作为输出 !!
  • 好像有错字。某处 x 应该是 5 int x = 5;
  • thanks..edited to int x =5;

标签: java overriding ocpjp covariant


【解决方案1】:

G 是声明的类型,H 是实际的类型。

声明的类型是您可以将对象视为的类型,即示例中的 G。

实际类型是对象实际上是什么,即您的示例中的 H 。这提供了实际行为,包括它可能从包括 G 在内的父类继承的任何行为。

【讨论】:

    【解决方案2】:

    当你重写一个方法时,重要的是实例的类型,而不是引用的类型。这就是多态性的工作原理。

    CovariantTest c1 = new SubCovariantTest();
    

    这会转换引用的类型,但不会转换实现。如果你这样做

    System.out.println(c1.getClass());
    

    这会打印出来

    SubCovariantTest
    

    因此,当您在此实例上调用 getObject() 时,调用 SubCovariantTest.getObject() 也就不足为奇了


    相比之下,static 方法不遵循多态性。它们不能以相同的方式被覆盖(它们只能被隐藏)如果你在这两种情况下都将getObject()设为静态,你会发现c1.getObject()会调用c1的匹配类型,因为调用的方法是在编译时确定,而不是运行时确定。事实上你可以这样做。

    public class CovariantTest {
    
        public G static getObject() {
            System.out.println("g");
            return new G();
        }
    
        public static void main(String[] args) {
            CovariantTest c1 = null;
            System.out.println(c1.getObject().x); // prints "g" "5"
        }
    }
    
    class SubCovariantTest extends CovariantTest {
    
        public H static getObject() {
            System.out.println("h");
            return new H();
        }
    }
    

    您可以在此处访问null 引用,因为它在运行时不使用。正如您在问题中所期望的那样,编译器仅使用引用的类型。

    【讨论】:

      猜你喜欢
      • 2015-12-04
      • 1970-01-01
      • 2021-08-24
      • 2013-10-27
      • 1970-01-01
      • 1970-01-01
      • 2020-12-08
      • 1970-01-01
      相关资源
      最近更新 更多