让我们说如果有两个类A和B,那么A扩展了B,因此按照惯例A可以访问B的非私有成员。那么为什么我们不能创建B的对象并将该引用分配给A。
A级
public class A extends B {
public static void main(String[] args) {
A a = new B();
B b = new A();
}
}
B类:
public class B {
}
我的主要问题是:
A a = new B();
不正确?B b = new A();
是正确的?答案 0 :(得分:8)
那么我们为什么不能创建B的对象并将该引用分配给A。
1)为什么
A a = new B();
不正确?
由于A
也(可能)具有B
不具备的功能,因此实例(即B
)不是一个{ {1}},因此您无法将A
实例分配给类型为B
的变量。
2)为什么
A
是正确的?
由于B b = new A();
的实例是 A
实例,因此它们可能还比B
实例多一点。因此,B
类型的变量引用一个B
实例是很好的(也是常见的)。请记住,继承是一种“是”关系。 A
表示一个A extends B
实例是一个 A
实例。
让我们使用更有意义的类名并包括一些状态:
B
因此class Super {
private int foo;
// ...details omitted...
}
class Sub extends Super {
private int bar;
// ...details omitted...
}
的实例具有一个Super
的数据槽:
+−−−−−−−−−−−−−−−−−−+ | (Super instance) | +−−−−−−−−−−−−−−−−−−+ | foo: 0 | +−−−−−−−−−−−−−−−−−−+
foo
的一个实例具有一个用于Sub
的插槽(因为它是一个 foo
)和一个用于Super
的插槽:< / p>
+−−−−−−−−−−−−−−−−−−+ | (Sub instance) | +−−−−−−−−−−−−−−−−−−+ | foo: 0 | | bar: 0 | +−−−−−−−−−−−−−−−−−−+
类型bar
的变量可以引用Super
实例;该实例具有Sub
拥有的所有数据插槽(以及行为,未显示)。但是类型Super
的变量不能引用Sub
实例;该实例没有Super
数据槽(以及可能的bar
特定行为,未显示)。
答案 1 :(得分:0)
您无法将超类实例分配给变量,因为您可能会遇到以下情况:从子类中调用方法。
在编译时和运行时,您会遇到相同的问题:如果子类中的方法在拥有类型超类的情况下在子类类型的变量上被调用,将会发生什么情况?超类不一定具有子类中的所有字段和方法。
以另一种方式工作,因为超类具有的所有内容,子类也具有。