为什么我们不能在当前类引用中保存超类对象?

时间:2018-07-18 14:55:15

标签: java class inheritance

让我们说如果有两个类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 { 

}

我的主要问题是:

  1. 为什么A a = new B();不正确?
  2. 为什么B b = new A();是正确的?

2 个答案:

答案 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)

您无法将超类实例分配给变量,因为您可能会遇到以下情况:从子类中调用方法。

在编译时和运行时,您会遇到相同的问题:如果子类中的方法在拥有类型超类的情况下在子类类型的变量上被调用,将会发生什么情况?超类不一定具有子类中的所有字段和方法。

以另一种方式工作,因为超类具有的所有内容,子类也具有。