我总是把这个问题烧在我身上。为什么人们将子类的对象分配给超类引用,如下所示:
让人们这样做的好处和原因究竟是什么?
public static void main(String[] args)
{
A obj1 = new C(); //Why do this ?
C obj2 = new C(); //When we can simply do this ???
}
class A
{}
class B extends A
{}
class C extends B
{}
我理解Class Dog是Animal的所有逻辑,但动物本质上不是Dogs。 我也碰到了这个链接:Why assign a subclass object to a superclass reference?我提出了与我类似的问题(但标记为重复,并附有不相关的链接:What does it mean to "program to an interface"?)
在这里:Why assign a subclass object to a superclass reference?一些模糊的答案是作为这样做的理由。不幸的是,在用不相关的链接标记重复之前,不能给出更详细的答案。
希望有人可以查看这个问题并详细回答将子类的对象分配给超类引用的原因。
答案 0 :(得分:2)
经典例子。存储可自行绘制的对象列表,并在需要时绘制它们。
List<Drawable> toDraw = new ArrayList<Drawable>();
// Add objects to draw
toDraw.add(new Circle(0, 0, 10));
toDraw.add(new Rectangle(10, 10, 20, 20));
// draw them
for (Drawable drawable : toDraw) {
// each object knows how to draw itself
drawable.draw();
}
如果明天有人实现了一个新的drawable(比如说三角形),那么这段代码仍然有用。
此代码也是Open-Close原则的一个示例,即代码为Open for extension,但Closed为修改。您不需要更改绘制所有对象的代码(修改),但您仍然可以添加新的drawable(扩展名)。
答案 1 :(得分:1)
简而言之:
Class Pet
Class Dog extends Pet
Class Cat extends Pet
Class Mouse extends Pet
你可以将宠物包裹在“一个”清单中,将它们作为宠物包裹起来:
List<Dog> dogs = new LinkedList<Dog>();
dogs.add(new Cat()) // error.
List<Pet> pets= new LinkedList<Pet>();
pets.add(new Cat()); //works
pets.add(new Dog()); //works
pets.add(new Mouse()); //works
现在,如果有人问你的宠物,你只有一个宠物清单:
for (Pet p : pets){
System.out.println(p) //prints dog, mouse and cat.
}
如果你保持最具体的类型,你需要保留3个列表来跟踪你的宠物。
请注意,向cat
提升的pet
不会使其失去特定的cat属性。当被视为宠物时,它们无法使用 - 您可以再次将它转发给猫以致电cat.mew()
或dog.bark()
。