What can polymorphism do that inheritance can't?
假设我们有一个类
这类动物具有
对于一只狗来说,这是"狗动"和"狗吃"。对于
现在,因为多态性,如果我这样做的话
1 | Animal charlietheBird = new Bird() |
然后打电话进来
1 | charlietheBird.talk() |
它将输出
Bird talking
因为输出是在运行时确定的,因为编译器知道charlie是类
然而!!
我可以简单地做
1 | Bird charlietheBird = new Bird(); |
然后调用
What can polymorphism do that inheritance can't?
多态性的真正优点可以在运行时看到,而不是在编译时看到。多态性允许您用一个实现替换另一个实现,而不需要更改使用它的代码。让我们以
1 2 3 4 5 6 7 8 9 10 11 | class Vet { private Animal animal; public Vet(Animal animal) { this.animal = animal; } public void perfromCheckup() { animal.talk(); animal.poop(); } } |
你现在可以说:
1 2 3 4 | Vet vetWithBird = new Vet(new Bird()); Vet vetWithDog = new Vet(new Dog()); vetWithBird.performCheckup(); vetWithDog.performCheckup(); |
请注意,您可以告诉
1 2 3 4 5 6 7 8 9 10 11 | class Vet { private Bird bird; public Vet(Bird bird) { this.bird = bird; } public void perfromCheckup() { bird.talk(); bird.poop(); } } |
可怜的
1 2 | Vet vetWithBird = new Vet(new Bird()); //Works fine. Vet likes birds. Vet vet = new Vet(new Dog())// compilation error. Sorry I don't like dogs. |
总之,多态性允许您替换使用超级类引用的子类实例。继承允许您从父类继承代码,并可能在子类中重新定义该行为,以便您的代码可以在运行时通过多态性利用它。
继承支持多态性,但多态性不依赖于继承。
您给出了一个如何通过继承实现多态性的示例。
但你可以用不同的眼光看待它:
移动概念有一个接口:
1 2 3 | interface Movable{ void move(); } |
动物可以实现这个接口:
1 2 3 4 5 6 | class Dog implements Movable { @Override public void move(){ // move the animal } } |
但是一些真菌也可以移动:
1 2 3 4 5 6 | class SlimeMold implements Movable { @Override public void move(){ // move the animal } } |
很难在这两者之间找到可以通过继承来表达的"is a"关系,但是当两者实现相同的接口时,我们仍然可以对它们应用多态性:
1 2 3 4 5 | Collection<Movable> movables = new HashSet<>(); movables.add(new Dog()); movables.add(new SlimeMold()); for(Movable movable : movables) movable.move(); |
继承是指Java编程的一个特性,它允许您创建派生自其他类的类。基于另一个类的类继承另一个类。继承的类是父类、基类或超类。
多态性是指编程语言根据对象的数据类型或类不同处理对象的能力。更具体地说,它是为派生类重新定义方法的能力。
您可以在比尔-维纳斯第7章中找到更多关于对象和Java的信息:多态性和接口