我想知道无法将父对象分配给子对象的技术原因。 例如:
Class Animal{}
Class Dog : Public Animal{}
Animal a = new Dog()
是可能的,但为什么
Dog g = new Animal()
是不可能的。
我知道,根据上述关系,狗“是动物而不是动物”是“狗”。但它背后的技术原因是什么呢?为什么我们不能分配呢?
答案 0 :(得分:3)
因为狗叫。一般来说,动物不会。
Dog g = new Animal();
g.bark();
g
如何知道吠叫?该任务是否神奇地将动物变成了狗?如果是鹦鹉怎么办?我们如何将鹦鹉变成狗?或者,如果作业没有转换任何东西,鹦鹉怎么会知道如何吠叫? (请注意,这是挪威蓝鹦鹉,它实际上并不知道怎么做任何。)
答案 1 :(得分:2)
这既是逻辑上的,也是技术上的原因 - Animal
的实例没有Dog
的所有方法和字段。例如:
class Animal {
public int legs;
}
class Dog extends Animal {
public int fangs;
}
Dog dog = new Animal();
dog.fangs = 5;
但您使用的是Animal
,但没有fangs
,因此会失败。
public doSomethingDoggish(Animal animal) {
((Dog) animal).bark();
}
但是如果你没有在那里传递Dog
的实例,它将在运行时失败。
答案 2 :(得分:2)
因为那时你可以写
Animal animal = new Rabbit();
Dog d = animal;
d.bark(); // but it's a Rabbit
答案 3 :(得分:1)
经典术语是“IS-A”,如“狗是一种动物”,但“动物不是狗”,在你们的关系中。
直观地说,为什么你可以将狗分配给动物,而不是相反。
答案 4 :(得分:1)
因为你的狗是动物。
Dog g = new Dog()
你现在有一个动物。它是一种特定类型的动物,但仍然是一种动物。它可以完成动物可以做的所有事情。
如果我只想把它当作动物来对待并忽略它是狗的事实,我可以用Animal a = new Dog()
来做到这一点
动物不是狗。它无法完成狗可以做的所有事情。所以如果我试着说Dog g = new Animal()
......我没有任何意义。我试图夺走使狗成为狗的一切。
答案 5 :(得分:0)
课程就像合同。当您定义Animal
课程时,您会说“这是动物,他可以这样做”。当你定义Dog
时,你会说“狗是动物,他可以做动物所做的一切,但他也可以这样做。”
现在,当你执行Animal a = new Dog()
时,这是正常的,因为Dog
可以执行Animal
所做的一切。
但当你执行Dog g = new Animal()
时,违反了合同,因为Animal
无法做到“那个”,只有Dog
可以。
答案 6 :(得分:0)
由于您要求技术原因,请考虑内存存储:“new Animal()”只需要足够的资源来存储所有动物所需的最小数据,但“新Dog()”需要更多资源 - 一个资源哺乳动物(毛皮,温暖的血液)和狗的资源(对松鼠的迷恋)。
但是,如果你问“一旦我写了'狗'一次,为什么我要再说一遍?”然后答案是“并非所有语言都需要这样。”