Ruby是否支持包含多态性

时间:2010-12-17 16:01:20

标签: ruby polymorphism duck-typing

Ruby支持“包含多态”吗?这和Duck Typing一样吗?

如果没有,Ruby中的多态和鸭子输入之间有什么区别?

有人可以用下面的例子说明:

# superclass - inheritance
class Animal
  def make_noise
    # define abstarct method (force override)
    raise NoMethodError, "default make_noise method called"
  end
end

# module - composition
module Fur
  def keep_warm
    # etc
  end
end

# subclass = is-a relationship
class Bird < Animal
  # override method - polymorphism
  def make_noise
    "Kaaw"
  end
end

class Cat < Animal
  # module mixin = has-a relationship
  include Fur

  def make_noise
    "Meow"
  end
end

class Radio
  # duck typing (no inheritance involved)
  def make_noise
    "This is the news"
  end
end

class Coat
  include Fur
end

animals = [Bird,Cat,Radio,Coat,Animal]

animals.each do |a|
  # polymorphism or duck typing?
  obj = a.new
  if obj.respond_to? 'make_noise'
    puts obj.make_noise
  end
end

1 个答案:

答案 0 :(得分:0)

在你的例子中,你可以说每个循环都有效,这要归功于鸭子打字(与客户端代码只关心变量可以产生噪音的事实有关),但猫和鸟可以产生噪音的事实是关于称为多态的子类机制的理论描述。

所以你可以说多态性和鸭子打字之间的区别在于多态性是你可以在任何情况下使用声称是某种类型的对象代替另一种对象的想法,但鸭子打字是你的想法不关心对象的类型,只要它实现某些接口即可。 因此,例如在Java中,如果你创建一个Animal的子类,你可以期望它不仅会产生噪音,还会产生与动物相关的其他行为,而在Ruby的情况下,一个物体可以产生噪音的事实不会不依赖于类型,只取决于特定方法的存在。 当然,在Java中,您有接口的概念,它为相同的模式提供(静态)机制。

最重要的区别IMHO是名称背后的不同编程哲学,而不是概念本身。

我想这一切都归结为这样一个事实,即多态性这个术语与更多结构化的OOP思想有关,而Ruby必须为一种具有不同可能性和含义的编程方式创造一个名称。