java-使用协变类型wrt变量重写

java-使用协变类型wrt变量重写,java,overriding,ocpjp,covariant,Java,Overriding,Ocpjp,Covariant,输出: 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) { Cova

输出:

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();
    }
}

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

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

声明的类型是您可以将对象视为的类型,例如在您的示例中


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

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

h
5
6
这将转换引用的类型,但不转换实现。如果你要做

CovariantTest c1 = new SubCovariantTest();
这会打印出来

System.out.println(c1.getClass());
因此,当您在此实例上调用
getObject()
时,调用
subcoveriantTest.getObject()


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

SubCovariantTest

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

您发布的代码永远不会得到5作为输出!!好像是打字错误。某处x应该是5
intx=5谢谢..编辑为int x=5;
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();
    }
}