没有继承的Ruby类覆盖

时间:2014-01-31 15:08:48

标签: ruby inheritance

我刚做了这个实验:

class A < Hash
  def foo
    'foo'
  end
end

class A < Hash
  def bar 
    'bar'
  end
end

到目前为止,我得到了我预期的结果,第二个声明扩展了第一个。但是我对此感到惊讶:

class A
  def call
    puts foo
    puts bar
  end
end

上面的代码有效,但只有我稍后再声明。否则我得到:

TypeError: superclass mismatch for class A

我可以假设在Ruby中,在确保解析“原始优先”声明后,跳过超类规范而没有副作用是安全的吗?

2 个答案:

答案 0 :(得分:3)

您只能在类定义的第一个发生时声明继承,因此下面的变体将起作用:

  1. 当您定义了相同的类继承时:

    class A < Hash
    end
    
    class A < Hash
    end
    
  2. 在第二种情况下使用默认继承时,将其视为未定义的继承:

    class A < Hash
    end
    
    class A
    end
    
  3. 在两种情况下使用默认继承时,默认继承为Object class:

    class A
    end
    
    class A
    end
    
  4. 以下不会:

    1. 当你在第一种情况下使用默认继承时,接下来你试图明确地重新定义它:

      class A
      end
      
      class A < Hash
      end
      
      TypeError: superclass mismatch for class A
      
    2. 当您在第一种情况下使用了指定的继承(在示例String中),然后您尝试显式重新定义它(例如Hash}):

      class A < String
      end
      
      class A < Hash
      end
      
      TypeError: superclass mismatch for class A
      

答案 1 :(得分:1)

@Малъ Скрылевъ以更好的方式解释了这个案例,所以我不会尝试这样做。但我会告诉你另一种方法。

避免错误的一种方法是在你的情况下:

而不是写

class A
  def call
    puts foo
    puts bar
  end
end

使用Module#class_eval编写如下:

  

在mod的上下文中计算字符串或块,除了在给出块时,常量/类变量查找不受影响。 这可用于向类添加方法。 module_eval返回评估其参数的结果。

A.class_eval do
  def _call
    puts foo
    puts bar
  end
end