class One{
}
class Two extends One{
}
class Main{
public static void main(String[] args){
Two t = new One(); // invalid
}`
}
我不理解其中的原因,为什么子类引用不能持有父类对象,而超类引用可以持有子类对象。
class One{
}
class Two extends One{
}
class Main{
public static void main(String[] args){
Two t = new One(); // invalid
}`
}
如果我们从集合论的角度来思考,与父类相比,子类是超集合。 子类拥有所有可能的属性和方法,与父类相比。
因此,父类对象可以引用其子类对象,因为子类对象包含了父类的方法和属性。反过来思考,由于父类对象没有子类所需的所有方法和属性,子类对象不能引用父类对象。
类型TWO不能是类型ONE的实例,因为TWO有一些成员和方法,而ONE没有。但是,类型ONE可以引用类型TWO,因为TWO拥有ONE拥有的一切。
例如,如果ONE可以走路,而TWO也可以跑步,那么如果您拥有一个ONE类型的对象,它需要能够走路。所以如果ONE引用了TWO就没问题,因为TWO可以走路。
但当您拥有类型TWO的对象时,它需要能够跑步,因此您无法将其引用到不能跑步的ONE上。
考虑一个名为Two的类,其中包含一个方法,假设为demo()。
class One{
}
class Two extends One {
void demo(){
System.out.println("in Two");
}
}
class Main{
public static void main(String[] args){
Two t = new One(); // Suppose this is valid at compilation time
t.demo();
}
}
现在假设当我们创建类One的对象时,编译器没有给我们报错,即子类引用持有父类对象。进一步地,t是类Two的引用,因此t.demo()是有效的。
现在当程序运行时,引用t包含类One的对象。当程序到达t.demo()时,t包含类One的对象,而类One没有名为demo()的方法。
因此,为了防止这种类型的错误,编译器检查对象是否是引用类型,即对象类与引用类相同或是引用类的子类。