【问题标题】:Does Ruby support inclusion polymorphismRuby 是否支持包含多态性
【发布时间】:2023-04-10 18:45:01
【问题描述】:

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

【问题讨论】:

  • 我的示例做出了我想确认的假设。例如,多态性仅限于使用继承的地方。鸭子类型说明了混合。我无法解决这个问题,书籍/维基百科等似乎存在相互矛盾的信息。

标签: ruby polymorphism duck-typing


【解决方案1】:

在您的示例中,您可以说每个循环的工作都归功于鸭子类型(与客户端代码只关心变量是否会产生噪音的事实有关),但 Cats and Birds 会产生噪音的事实是称为多态性的子类机制的理论描述。

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

恕我直言,最重要的区别在于名称背后的不同编程哲学,而不是概念本身。

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

【讨论】:

  • 感谢您的快速回复。所以你是说多态性仅限于涉及继承的地方?这是否意味着涉及继承时鸭子类型与多态性相同?
  • 我不认为多态性的定义依赖于继承,我也不认为它本身很普遍,这是维基百科条目:在强类型语言中,多态性通常意味着类型A 以某种方式派生自类型 B,或者类型 C 实现了表示类型 B 的接口。在弱类型语言中,类型是隐式多态的。
  • 我在下面的链接中找到了一个定义,其中指出“多态性(非常简单地说)是在需要基类的情况下使用派生类的可能性”。在像 Ruby 这样的动态类型语言中,没有“预期的”类,所以通过这种推理,多态性不适用于 Ruby?例如,这就是区分鸭子类型和多态性的原因吗? stackoverflow.com/questions/3343625/…
猜你喜欢
  • 1970-01-01
  • 2013-04-28
  • 1970-01-01
  • 2015-11-19
  • 2015-10-29
  • 2013-05-26
  • 1970-01-01
  • 2017-03-27
  • 1970-01-01
相关资源
最近更新 更多