【问题标题】:Ruby's Single Inheritance IssueRuby 的单一继承问题
【发布时间】:2017-12-09 20:11:24
【问题描述】:

我需要一些帮助来定义一个示例来说明为什么 Ruby 中的单继承是一个问题。 单类继承不能解决这个问题。

考虑一下这是一个抽象的例子,说明 Ruby 在 OO 方面面临的限制。我试着举了几个例子,但总是不够用。

我们的想法是使用模块来解决 Ruby 面临的这个问题。

非常感谢任何帮助。如果您在下面看到我的示例,很高兴获得有关它是否证明上述问题的任何反馈。

Person 超类和 Pet 超类不属于同一个类层次结构,但共享同一个实例方法swim。出于这个原因,游泳实例方法被放置在一个模块中,并混合到每个超类中。

module Swimming
    def swim
      puts 'I can swim'.
    end
end

class Person

    include Swimming

    def initialize(name)
      @name = name
    end
end

class Boy < Person 
end

class Pet
    include Swimming

    def initialize(name)
      @name = name
    end
end

class Fish < Pet
end

new_boy = Boy.new('Oliver')
new_fish = Fish.new('Ronald')

【问题讨论】:

  • 很难想出一个需要多类继承来解决的问题,尤其是当你有 mixin 模块时。
  • 是的,mixin 几乎解决了大多数实际用例的继承问题。您可能会发现在没有 mixin 或特征的 Java 这样的语言中做这样的事情会更容易。
  • 我想我的意思是我需要一个不能用单继承解决的问题,只能用 mixin 解决
  • 你需要这个做什么?如果很难举出一个例子,那么您的“Ruby 中的单一继承是一个问题”的前提可能有点偏离。
  • 可以通过使用 mixins 或其他语言的协议来避免多重继承。没有单继承解决不了的问题。总有办法,问题是解决方案与多重继承相比有多难看。

标签: ruby oop inheritance conceptual


【解决方案1】:

只要你想包含来自多个地方的功能,就可以使用 Mixin。其他一些语言使用多重继承。

module Swimming; end
module Bicycling; end

class Person
  include Swimming
  include Bicycling
end

如果有一个类只使用一个 mixin,那么它可以很容易地更改为基于继承的实现:

class Swimming; end # not a module
class Amoeba < Swimming
end

但是如果不创建包装模块的中间类,就无法对 Person 类进行类似的操作。

class SwimmingAndBicycling
  include Swimming
  include Bicycling
end
class Person < SwimmingAndBicycling
end

因此,模块确实是将 2 多个功能组合成第三个功能的唯一简单方法。 Ruby 是一种非常灵活的语言,有一些方法可以解决这个问题,例如手动将方法从一个类复制到另一个类。但这是标准方法。

另外值得一提的是,类和模块有一些实际差异,我在这里不做介绍。例如,在继承中,所有实例和类方法都被复制过来,但是对于模块,这取决于是否调用了 include 或 extend。

【讨论】:

  • include 只是使模块成为它所包含的类的超类(更准确地说,它创建一个与模块共享其方法、常量、类变量和实例变量表的类,并使该类成为该类的超类)。所以,Ruby中的mixin继承单类继承。 (extend 或多或少是一回事,大致相当于singleton_class.include。)所以,其实你并不是在证明 Ruby 的单类继承有问题,而是在证明 Ruby 的单类继承不是有问题!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多