如果一个数组有一个Bird,Dog,Cat,Fish对象,我在它们上面调用.move(),这被认为是多态吗?

时间:2015-12-16 02:01:21

标签: oop polymorphism

我在维基百科和其他文本中看到以这种方式提供多态的例子:

1)如果有一个包含4个Animal对象的数组,它们实际上是Bird,Dog,Cat,Fish类,然后循环遍历它们,并调用animal.move(),(其中animal是一个通用的动物指针),那将是多态性。

2)如果我有一个Dog对象,但我将它传递给普通函数moveIt(Animal *animal)并且在里面,它使用animal.move()来调用move(),我们可以传入一个Fish对象(moveIt(fish))也是如此,它也会做正确的事情,这就是多态性。

我认为没关系,这些例子显示了一个通用的动物对象能够(明智地)调用适当的方法作为狗或鱼,这是多态性。

但是在JavaScript或Ruby等语言中,数组元素可以是任何类型。所以它不是一个包含4个动物对象的数组,而是一个[bird, dog, cat, fish]数组,现在我们遍历数组并调用它:

# In Ruby:

bird = Bird.new()
dog = Dog.new()
cat = Cat.new()
fish = Fish.new()

arr = [bird, dog, cat, fish]
arr.each do |i|
  i.move()
end

现在在这种情况下,因为它们从未成为“通用”动物,当然我们希望dog.move()表现为狗的运动方式,所以在这种情况下,严格来说,它仍然是多态的吗?

2 个答案:

答案 0 :(得分:1)

是的,它的运行时多态性,即。不是基于继承。从技术上讲,它被称为鸭子打字,例如,如果它像鸭子一样走路,那就像鸭子一样说话......

对象都有move()方法,因此语言允许仅通过方法签名进行动态调用。

https://en.m.wikipedia.org/wiki/Duck_typing

许多人都熟悉的基于继承的多态现象是子类重写其中一个超类的一个或多个方法的行为。调用该方法时,将根据对象类执行特定的子类实现。

答案 1 :(得分:0)

不,因为他们并非都从同一个基类继承。

您希望用来描述这一术语的术语是duck typing。您提供的代码示例之所以有效只是,因为它(可能是您的设计)发生了数组中的每个对象都有适当的方法。