代码之家  ›  专栏  ›  技术社区  ›  TechnocratSid

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

  •  1
  • TechnocratSid  · 技术社区  · 8 年前

    假设有两个类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 回复  |  直到 8 年前
        1
  •  8
  •   T.J. Crowder    8 年前

    那么为什么我们不能创建一个b的对象,并把这个引用赋给a呢?

    1)为什么 A a = new B(); 是否不正确?

    因为 A 还有(潜在的)功能 B 没有,因此实例(它是 ) 不是 ,因此无法分配 实例到 -类型化变量。

    2)为什么 B b = new A(); 是否正确?

    因为 例如,它们也可能比 实例。所以对于一个 -要引用的类型化变量 实例。记住,继承是一种“是”的关系。 A extends B 表示 实例 是一个 实例。

    让我们使用更有意义的类名并包括一些状态:

    class Super {
        private int foo;
        // ...details omitted...
    }
    
    class Sub extends Super {
        private int bar;
        // ...details omitted...
    }
    

    所以一个例子 Super 有数据槽用于 foo :

    +−−−−−−−−−−−−−−−−−−+
    | (Super instance) |
    +−−−−−−−−−−−−−−−−−−+
    | foo: 0           |
    +−−−−−−−−−−−−−−−−−−+
    

    的实例 Sub 有一个插槽 (因为它 是一个 超级的 )还有一个插槽 bar :

    +−−−−−−−−−−−−−−−−−−+
    |  (Sub instance)  |
    +−−−−−−−−−−−−−−−−−−+
    | foo: 0           |
    | bar: 0           |
    +−−−−−−−−−−−−−−−−−−+
    

    类型的变量 超级的 可以引用 附属的 实例;该实例具有 超级的 有。但是类型的变量 附属的 不能引用 超级的 实例;该实例没有 酒吧 数据槽(可能 附属的 -具体行为,未显示)。

        2
  •  0
  •   Absent    8 年前

    无法将超类实例分配给变量,因为可能会遇到需要从子类调用方法的情况。

    在编译时和运行时,您会遇到同样的问题:如果子类中的一个方法在保存类型超类的同时对类型子类的变量调用,会发生什么?超类不一定具有子类中的所有字段和方法。

    另一种工作方式是,因为超类拥有的一切,子类也拥有。