我正在阅读Kathy Sierra的SCJP书。我发现多态性有点令人困惑。
你可以帮我解决下面这个真实世界的例子吗?
我知道Polymorphism只有在重写方法时才会起作用,无论你是通过类还是接口来实现的,并且在运行时JVM根据Object类型确定方法。
让我们说Horse从Animal扩展而且它也覆盖了eat()方法。这样做有什么好处:Animal a = new Horse(); a.eat();
超过Horse b = new Horse();
b.eat();
?
最终结果将是相同的。我向它提出了一个非常基本的问题,但即使我团队中的所有高级开发人员都给了我不同的答案。
答案 0 :(得分:15)
为了扩展你的榜样,假设你有一个动物农场。然后可以将所有动物的集合定义为
List<Animal> animals = new ArrayList<Animals>();
animals.add(new Horse());
animals.add(new Cow());
animals.add(new Sheep());
然后你可以迭代所有的动物并让它们全部吃掉
for(Animal a: animals) {
a.eat();
}
它们对设计模式也很重要。我建议您阅读@ http://en.wikipedia.org/wiki/Design_pattern_(computer_science)
答案 1 :(得分:6)
想象一下,你有动物类和三种实现:马,牛和猪。然后你有一个他们走路的地方。因此,您可以进行以下操作:
List<Animal> animals = new ArrayList<Animal>(3);
animals.add(new Horse());
animals.add(new Cow());
animals.add(new Pig());
for (Animal animal : animals) {
animal.eat();
}
所以在这个循环中,你不介意你拥有什么样的混合动物:它可以是猪,也可以是牛,或者完整的清单可以只用马匹填充。但他们都是动物,他们都可以吃。多态性在这里是很好的,因为独立于你拥有的动物,所以吃的方法将根据具体物体的选择来选择。
答案 2 :(得分:3)
假设你有一个农场。
List<Animal> farm = new ArrayList<Animal>();
farm.add(new Horse());
farm.add(new Pig());
farm.add(new Chicken());
现在让它们全部吃掉。
for(Animal animal : farm){
animal.eat();
}
答案 3 :(得分:2)
如果您只有一个子类,则无法明确地看到优势,但假设您还有第二个名为Lion的子类:
public abstract class Animal {
public abstract void eat;
}
public class Horse extends Animal {
public void eat() {
System.out.println("Eats gras");
}
}
public class Lion extends Animal {
public void eat() {
System.out.println("Eats meat");
}
}
现在你有一份动物清单,你可以这样做,它会打印出正确的食物:
List<Animal> animals = new List<Animal>();
animals.add(new Lion());
animals.add(new Horse());
for(Animal a: animals) {
a.eat();
}
答案 4 :(得分:2)
容易...
想象一下,你有几个课程扩展动物(如马,狗,猫,鸭)并将所有动物对象放入一个列表,然后你可以一次性喂它们
for (Animal a: animalList) {
a.eat();
}
并且所有人都在不需要了解的情况下喂养,需要喂什么样的动物。好。你的动物扩展课程必须确保他们吃正确的东西,但这就是重点。
答案 5 :(得分:0)
在动物a =新马(); a.eat()案例a 无法调用一个特定于马的方法,如在马b = new Horse();击败(); b可以打电话。
特定马匹指马中的方法,但不是动物。
作为动物的参考,它不知道在马中声明的特定于马的方法。
更像是像Animal a = new Horse();因为你静态分配实例,所以不会那么重要。在您不知道运行时将具有哪个子类实例的情况下,多态性更有用。
答案 6 :(得分:0)
多态性是关于共享基础但做不同事物的对象。例如,想象一下创建一个国际象棋程序。如果你能管理一些Pieces,那将是非常好的。你不需要知道这些棋子是棋子,骑士,国王,女王等......你只需要知道这件作品的某些事情。该作品可以有方法确定其点值,确定哪些空间对于它移动有效,给定一块其他棋子等等......
你也可以制作俄罗斯方块游戏。当你从屏幕顶部添加新的部分时,它使代码更加可重用,可以处理所有相同但具有不同行为的部分(旋转块和旋转线条非常不同)。
希望这有助于您了解实用性。我意识到这些只是游戏的例子,但我认为它们很好地说明了这一点。