用协变类型wrt变量重写java
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语句是不同的。如何将从类SubCovenant的getObject方法返回的新H()对象分配给G引用
# 1 楼答案
重写方法时,重要的是实例的类型,而不是引用的类型。这就是多态性的工作原理
这将转换引用的类型,但不转换实现。如果你要做
这会打印出来
因此,当您在这个实例上调用
getObject()
时,调用SubCovariantTest.getObject()
就不足为奇了相比之下,
static
方法不遵循多态性。如果要使getObject()
在这两种情况下都是静态的,c1.getObject()
将调用匹配的c1
类型,因为要调用的方法是在编译时而不是运行时确定的,因此不能以相同的方式重写它们(只能隐藏它们)。事实上,你可以做到这一点您可以在此处访问
null
引用,因为它在运行时未被使用。编译器只使用引用的类型,正如您在问题中所期望的那样# 2 楼答案
G是声明的类型,H是实际类型
声明的类型是您可以将对象视为的类型,例如在您的示例中
实际类型是对象的实际类型,即示例中的H。这提供了实际的行为,包括它可能从父类(包括G)继承的任何行为