【问题标题】:When can Ruby classes have multiple superclassesRuby 类什么时候可以有多个超类
【发布时间】:2013-10-28 17:53:38
【问题描述】:

为什么下面的代码会按照我的预期运行?我的印象是一个类只能有一个超类,并且在第一次定义该类时放置原始超类以外的其他内容会引发类型不匹配异常。

class Test
end

class MyTest < Test

  def run
    p 'my test'
  end
end

class MyTest < Object

  def run
    p 'redefine my test'
  end
end

MyTest.new.run

结果

redefine my test

【问题讨论】:

    标签: ruby class inheritance


    【解决方案1】:

    仅当第二个类声明继承自 Object 时,它才适用于我(Ruby 1.9.2 和 1.9.3)。任何其他 MI 尝试都会抛出 TypeError

    它也不会改变类的继承。所以MyTest.superclass 仍然是Test,即使在class MyTest &lt; Object 之后也是如此

    我认为这是因为Object 是定义新类时默认的superclass。来自docs

    new(super_class=Object) → a_class
    

    因此,当Object 作为superclass 给出时,它在不匹配检查中被忽略,因为不知道Object 是用户输入还是默认值。

    【讨论】:

      【解决方案2】:

      从来没有。 Ruby 确实支持 MI(但将特征视为有用的替代方案)。

      无论如何,这个类的重新定义是不明确的,并且会根据特定的 Ruby 实现产生不同的效果。当我运行给定的代码时,我得到“TypeError: superclass mismatch for class ..”(Ruby 1.9.2;1.9.3 出现延迟错误)。

      如果有问题的代码没有导致这样的错误,请检查MyTest.superclass 以查看重定义后的超类真正是什么:注意#superclass 返回一个单个 类对象,而不是集合。

      这里是一个反例,认为这个重新定义场景确实没有添加或指示 MI:

      class A
         def a; "a"; end
      end
      class B
         def b; "b"; end
      end
      class C < A
      end
      # This may raise said TypeError, but if it does not then ..
      class C < B
      end
      # .. either this will work
      C.new.a
      # .. /or possibly/ this will work
      C.new.b
      # If the redefinition added MI then /both/ would work.
      # If such an implementation is found, please let me know!
      

      (如果不引发所述 TypeError,我无法让上述工作。)

      【讨论】:

      • 虽然在一般情况下是正确的,但 OP 的问题有一点微妙之处。我怀疑@tihorn 的答案是正确的。
      猜你喜欢
      • 1970-01-01
      • 2018-07-01
      • 2011-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-10
      相关资源
      最近更新 更多