2014-01-31 70 views
4

我刚刚做这个实验的Ruby类覆盖:没有继承

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中,它是安全的确保“原第一”的宣言后,解析跳过无副作用的超规格?

+0

是的,这是正确的。 –

+0

在你最后一次尝试中,它会尝试创建一个“Object”类,作为它的超类。所以,你得到的错误......并且是预期的。 –

回答

3

你能只在类定义的第一occurince宣布继承,所以下面的变体将工作:

  1. 当你定义的相同类的继承:

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

    class A < Hash 
    end 
    
    class A 
    end 
    
  3. 当你使用默认继承在这两种情况下,默认的继承是Object类:

    class A 
    end 
    
    class A 
    end 
    

的,下面将不会:

  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

@Малъ Скрылевъ解释这种情况下更好方式,所以我不会尝试。但我会告诉你另一种方式来做到这一点。避免错误

的一种方法是在您的情况:

而是写作的

class A 
    def call 
    puts foo 
    puts bar 
    end 
end 

写如下使用Module#class_eval

评估了上下文中的字符串或块除了给定一个块时,常量/类变量查找不受影响。 这可以用于将方法添加到类module_eval返回评估其参数的结果。

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