多态性与遗传

时间:2013-04-05 16:30:46

标签: java polymorphism

假设我有两个类:Animal和Dog。狗是动物的一个子类。我执行以下代码:

Animal a = new Dog();

现在我可以通过一个变量调用Dog类的方法。

但我的问题是:如果我可以通过Dog对象(继承)调用所有Animal的方法而不是为什么我应该使用多态原理?我可以宣布:

Dog d = new Dog();

使用此声明可以使用Animal的所有方法和Dog方法。那么为什么要使用多态?非常感谢你的回答。

6 个答案:

答案 0 :(得分:23)

在Java中,多态性和继承的概念是“焊接在一起”;一般来说,它不一定是这样的:

  • Polymorphism允许您在不知道类的确切类型的情况下调用类的方法
  • 继承允许派生类共享其基类的接口和代码

有些语言的继承与多态性脱钩:

  • 在C ++中,您可以继承一个类而不会产生多态行为(即不使用virtual在基类中标记函数)
  • 在Objective C中,您可以在不相关的类上实现一个方法,并从只知道该方法签名的地方调用它。

回到Java,使用多态的原因是将代码与其对方的实现细节分离:例如,如果你可以编写一个适用于各种动物的方法Feed(Animal animal) ,当您添加更多子类或Animal的实现时,该方法将保持适用。这与Feed(Dog dog)方法形成对比,后者将与狗紧密耦合。

至于

Dog d = new Dog();
声明说,如果你知道你的方法的其余部分特别针对狗,那么没有一般理由可以避免这种情况。但是,在许多情况下,后者并非如此:例如,您的类或您的方法通常对确切的实现不敏感,例如

List<Integer> numbers = new ArrayList<Integer>();

在这种情况下,您可以将new ArrayList<Integer>()替换为new LinkedList<Integer>()知道您的代码将要编译。相反,如果您的numbers列表被声明为ArrayList<Integer> numbers,则此类切换可能不太确定。

这称为“编程到接口”。 Stack Overflow上有一个非常好的answer来解释它。

答案 1 :(得分:4)

您可以拥有Animal类的其他实现,例如Cat。然后你可以说

Animal a = new Dog();
Animal b = new Cat();

您可以调用Animal类的方法而不关心它实际上是哪种实现,polymorphism将调用正确的方法。 E.g。

a.speak();  // "Woof"

b.speak();  // "Meow"

实际上,它不是“多态与继承”,而是“使用继承的多态”。

答案 2 :(得分:4)

Polymorphism允许您编写适用于任何Animal的方法:

public void pet(Animal animal) {
   ...
}

此方法将接受DogCat等,包括尚未编写的Animal的子类。

如果该方法采用Dog,则不适用于Cat等。

答案 3 :(得分:1)

如果你确定它永远是一只狗,那就没有理由。您也可以按照您的描述使用 Dog d = new Dog(); 。但是,假设您使用的是方法而不是构造函数。该方法返回了一只动物,你不知道你会得到哪种动物。你仍然可以在动物身上使用相同的方法(即使它是狗,象猫等)。

为了可扩展性,继承简化了事情。当你想要创造一个也分享一些动物方法的大象或猫时,你可以通过让动物成为超级类来轻松获得它们。

答案 4 :(得分:0)

通常你问的问题更类似于继承与组合:)更多“现实生活”的例子,为什么使用多态性是好的,例如使用策略设计模式。您可以有许多TaxPolicy实现:UsaTaxPolicy,CanadaTaxPolicy,EuTaxPolicy等。如果您有方法calculateFinalPrice,它还必须计算税,那么您注入了正确的实现并执行了良好的计算,无论您是否通过了Usa,Canada或Eu实施。

答案 5 :(得分:0)

继承是动态多态。我的意思是当你删除继承时,你不能再覆盖。