为什么创建子类类型的父类的对象是不可能的,但可以反转?

时间:2017-10-09 09:10:28

标签: java object inheritance

我看过this-Downcasting is not possible但没有为什么实际上这是不可能的,下面是代码片段

class Parent {

}

public class Inherit  extends Parent{
    public static void main(String[] args) {
        Parent parent = new Inherit()  //No Error
        Inherit sub = new Parent();  // Type mismatch error
    }
}

我的问题是为什么创建子类型的父对象是可能的(Parent a = new Inherit())但是为什么不可能反转?实际原因是什么(type mismatch除外)

4 个答案:

答案 0 :(得分:2)

一个简单的例子:

class Parent {
  public String name;
}

class Inherit extends Parent {
  public int age;
}

因此,每个Inherit都有一个名称,但Parent没有年龄。如果您致电以下内容,该怎么办:

Inherit sub = new Parent();
sub.age; // ERROR: because a parent has no age

因此无法将父对象分配给子类引用,因为某些内容可能会丢失,就像@OH GOD SPIDERS指出的那样。

答案 1 :(得分:1)

免责声明:超级(过度)简单直观的解释,无需了解正确的技术细节。

我首先要指出,在特殊情况下,可能是可能的;特别是在父母的父母身上。通过向上传播一个孩子而创造的对象"宾语。希望这一点的原因将在一秒钟内明确。

假设您有Parent个字段x的对象 还有一个Child对象,它使用另一个字段y进行扩展。

当您正常实例化Parent对象时,java会分配足够的内存来保存x
实例化Child对象时,java会分配足够的内存来同时保存xy

当您将Child对象转换到Parent对象时,内存布局不会改变; java只是忽略为y保留的内存位,并处理对该对象的所有调用,就像它只包含x一样。

但是如果你试图将Parent对象向下转换Child对象,你基本上会错过引用y的位对象的内存占用。由于意图是铸造'之一。

,而不是"将对象复制到其他地方",不允许在这种情况下进行投射。

如果Parent对象最初是通过向上转换Child对象获得的,则可以将其向下转换回Child对象; java将此视为一种特殊情况,因为内存布局允许它。

这也是将向下转换视为运行时错误而不是编译错误的原因。

<子> PS。请注意,由此得出的推论是,当一个在实例化时向上转换,而在代码中将其视为Parent对象时,整个Child对象存储在内存中 - 这就是成功向下转换的原因返回Child对象可以随时重现。

答案 2 :(得分:1)

考虑继承关系。子类的对象是和父类的对象,它具有所有属性和方法,而反转肯定不是真的。

例如:

class Parent{
    public void methodA(){ ... };
}

class Child extends Parent{
    public void methodB(){ ... };
}

public class Main{
    public static void main(String[] args) {
        Child p = new Parent();
        p.methodA(); //Ok, parent object has method A
        p.methodB(); // parent object does not have method B, 
                     //but Child class exposes it. what happens here?
    }
}

答案 3 :(得分:0)

在OPPS概念中,继承遵循父类和子类之间的 IS-A 关系,这意味着如果child class (Jeep)扩展parent class(vehicle),那么您可以说Jeep IS-A 车辆,但反之亦然。假设Jeep类具有wheels属性

class Vehicle {
  public Date madeYear;
  public void start(){}
}

class Jeep extends Vehicle {
  public int wheels;
}

Jeep jeep = new Vehicle(); //Its not valid because vehicle object don't have wheels property which you can try to access from jeep reference variable.