inheritance类中的Ruby和类变量

class A def set(v) @@v = v end def put puts @@v end end class B < A end class C  b C.new.set 'c' C.new.put # => c B.new.put # => c 

为什么? 我怎么写这个在最后B.new.put中有’b’?

这是一篇关于这个主题的好文章 – Ruby中的类和实例变量 。

基本上,你可以做的是:

 class A class << self attr_accessor :class_var end def set_class_var(value) self.class.class_var = value end def get_class_var self.class.class_var end end class B < A; end A.class_var = 'a' B.class_var = 'b' puts A.class_var # => a puts B.class_var # => b A.new.set_class_var 'aa' B.new.set_class_var 'bb' puts A.new.get_class_var # => aa puts B.new.get_class_var # => bb 

要理解它,你应该将A视为Class类的一个实例(这就是它在Ruby中的实例)。 但Ruby中的每个对象都有自己的单例类,它存储对象特定的东西,比如在对象本身上定义的方法:

 a = A.new def a.foo puts 'foo' end 

在这种情况下, foo是仅为对象定义的方法,而不是为A类的每个实例定义的方法。 另一种在object的singleton类中定义方法的方法是这样的:

 class << a # open a's singleton class def bar # define method that will be available only on 'a' object puts 'bar' end end 

在第一个代码片段中,我们使用该方法在我们的A类的单例类的上下文中定义class_var属性访问器(这有点棘手,所以你需要考虑它)。 因为结果类本身具有class_var变量以及它的后代类B 不同之处在于它们中的每一个都有自己的class_var变量,不会产生干扰。

另一种选择是从Rails中提取class_inheritable_accessor代码并在其类中包含它的行为。 请参阅此处以获得良好的讨论和代码的内容。

不过,也许你真的不想要一个类变量。

为类变量(@@变量)赋值可以为类的每个实例设置它。 它甚至为“尚未创建”的实例“设置”它。 所以,考虑一下……

 B.new.set 'b' # OK, that set @@v for that particular instance of B B.new.put # Hey, you just created *another* new instance of B! 

@@ v如何在那个中有价值? 第二个对象的@@ v值将被取消, 除了 @@ v是一个类变量 ,因此它对于该类的每个实例都具有相同的值。