java 多态与继承
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15838978/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Polymorphism vs Inheritance
提问by Assaf
Suppose I have two classes: Animal and Dog. Dog is a subclass of Animal. I do the following code:
假设我有两个类:Animal 和 Dog。Dog 是 Animal 的一个子类。我执行以下代码:
Animal a = new Dog();
Now I can call methods of the Dog class through the a variable.
现在我可以通过 a 变量调用 Dog 类的方法。
But my question is this: if I can call all of Animal's methods through the Dog objects (inheritance) than why should I use the polymorphism principle? I can just declare:
但我的问题是:如果我可以通过 Dog 对象(继承)调用所有 Animal 的方法,那么我为什么要使用多态原则?我可以声明:
Dog d = new Dog();
With this declaration can use all of Animal's methods and Dog methods. So why use polymorphism? Thank you very much for your answer.
有了这个声明,可以使用所有的 Animal 方法和 Dog 方法。那么为什么要使用多态呢?非常感谢您的回答。
回答by dasblinkenlight
In Java, the concepts of polymorphism and inheritance are "welded together"; in general, it does not have to be that way:
在Java中,多态和继承的概念是“焊接在一起的”;一般来说,不必如此:
- Polymorphism lets you call methods of a class without knowing the exact type of the class
- Inheritance lets derived classes share interfaces and code of their base classes
- 多态性使您可以在不知道类的确切类型的情况下调用类的方法
- 继承允许派生类共享其基类的接口和代码
There are languages where inheritance is decoupled from polymorphism:
有些语言将继承与多态分离:
- In C++ you can inherit a class without producing polymorphic behavior (i.e. do not mark functions in the base class with
virtual
) - In Objective C you can implement a method on an unrelated class, and call it from a place that knows only the signature of the method.
- 在 C++ 中,您可以继承一个类而不产生多态行为(即不要用 标记基类中的函数
virtual
) - 在 Objective C 中,你可以在一个不相关的类上实现一个方法,并从一个只知道方法签名的地方调用它。
Going back to Java, the reason to use polymorphism is decoupling your code from the details of the implementation of its counter-parties: for example, if you can write a method Feed(Animal animal)
that works for all sorts of animals, the method would remain applicable when you add more subclasses or implementations of the Animal
. This is in contrast to a Feed(Dog dog)
method, that would be tightly coupled to dogs.
回到 Java,使用多态的原因是将您的代码与其对应方的实现细节解耦:例如,如果您可以编写一个Feed(Animal animal)
适用于各种动物的方法,那么该方法将在您添加更多子类或Animal
. 这Feed(Dog dog)
与与狗紧密耦合的方法形成对比。
As far as the
至于
Dog d = new Dog();
declaration goes, there is no general reason to avoid this if you know that the rest of your method deals specifically with dogs. However, in many cases the later is not the case: for example, your class or your methods would often be insensitive to the exact implementation, for example
声明说,如果您知道您的方法的其余部分专门针对狗,则没有一般的理由可以避免这种情况。但是,在许多情况下,后者并非如此:例如,您的类或您的方法通常对确切的实现不敏感,例如
List<Integer> numbers = new ArrayList<Integer>();
In cases like that, you can replace new ArrayList<Integer>()
with new LinkedList<Integer>()
, and knowthat your code is going to compile. In contrast, had your numbers
list been declared as ArrayList<Integer> numbers
, such switchover may not have been a certainty.
在这种情况下,您可以替换new ArrayList<Integer>()
为new LinkedList<Integer>()
,并且知道您的代码将被编译。相比之下,如果您的numbers
列表被声明为ArrayList<Integer> numbers
,这种转换可能不是确定的。
This is called "programming to an interface". There is a very good answeron Stack Overflow explaining it.
这称为“编程到接口”。Stack Overflow 上有一个很好的答案来解释它。
回答by rgettman
You can have other implementations of the Animal
class, such as Cat
. Then you can say
您可以拥有Animal
该类的其他实现,例如Cat
. 那你可以说
Animal a = new Dog();
Animal b = new Cat();
You can call methods of the Animal
class without caring which implementation it really is, and polymorphismwill call the correct method. E.g.
你可以调用Animal
类的方法而不用关心它到底是哪个实现,多态会调用正确的方法。例如
a.speak(); // "Woof"
b.speak(); // "Meow"
Really, it's not "Polymorphism vs Inheritance" but "Polymorphism using Inheritance".
真的,这不是“多态与继承”,而是“使用继承的多态”。
回答by NPE
Polymorphism allows you to write a method that works for any Animal
:
多态性允许你编写一个适用于任何的方法Animal
:
public void pet(Animal animal) {
...
}
This method would accept Dog
, Cat
, etc, including subclasses of Animal
that are yet to be written.
此方法将接受Dog
、Cat
等,包括Animal
尚未编写的子类。
If the method were to take Dog
, it would not work for Cat
etc.
如果该方法采用Dog
,它将不适用于Cat
等。
回答by Peter Rasmussen
If you are certain that it will always be a dog there is no reason for it. You might aswell use Dog d = new Dog();as you described. But let's say you used a method instead of a constructor. The method returned an animal and you wouldn't know which implementation of animal you would get. You would still be able to use the same methods on the animal (even if it's a Dog, Elephant cat etc).
如果你确定它永远是一只狗,那就没有理由了。你也可以使用Dog d = new Dog(); 正如你所描述的。但是假设您使用了方法而不是构造函数。该方法返回了一个动物,你不知道你会得到动物的哪个实现。您仍然可以对动物使用相同的方法(即使它是狗、象猫等)。
For extensibility purposes inheritance simplifies things. When you want to create an elephant or cat which also share some animal methods, You can easily get those by having animal as super class.
出于可扩展性的目的,继承简化了事情。当你想创建一个大象或猫也共享一些动物方法时,你可以通过将动物作为超类来轻松获得它们。
回答by Jakub Kubrynski
Normally the question you've asked is more similar to Inheritance vs Composition :) More "real life" example of why it's good to use polymorphism is for example usage of strategy design pattern. You can have many TaxPolicy implementation: UsaTaxPolicy, CanadaTaxPolicy, EuTaxPolicy, etc. If you have method calculateFinalPrice, which have to also calculate tax, then you inject the proper implementation and good calculation is executed, no matter you've passed Usa, Canada or Eu implementation.
通常,您提出的问题更类似于继承与组合 :) 更多“现实生活”的例子说明为什么使用多态是好的,例如使用策略设计模式。您可以有许多 TaxPolicy 实现:UsaTaxPolicy、CanadaTaxPolicy、EuTaxPolicy 等。如果您有方法 calculateFinalPrice,也必须计算税款,那么您注入正确的实现并执行良好的计算,无论您通过美国、加拿大还是欧盟实施。
回答by Alireza Rahmani Khalili
inheritance is the dynamic polymorphism. I mean when you remove inheritance you can not override anymore.
继承是动态多态。我的意思是当你删除继承时,你不能再覆盖了。