Rubyist

慎用类变量

类变量可以被该类以及其子类共享。如果一个类A定义了一个@@a变量,那么子类B可以使用这个变量表面上看起来继承了这个变量,其实还是有区别的。

设想为类变量赋值的情形会让这些区别更清楚。如果子类为一个已在超类中使用的类变量赋值,它不会创建这个类变量的私有拷贝,而是直接修改了父类中那个变量,同时所有其他子类也会看到这个被修改的值。看下面的例子。

 
class A
  def initialize
    @@count ||= 1
  end
  
  def self.count
    @@count
  end
end

class B < A
  def incr_count
    @@count += 1
  end
end

class C < A

end

A.new
puts A.count # => 1
B.new.incr_count
puts A.count # => 2
puts C.count # => 2

PS:《Ruby编程语言》一书上说当以警告模式运行的时候,Ruby1.8会对这种做法发出一个警告,1.9则不会。而实际上我在用1.8.6、REE、1.9.2测试都未发现警告…

这看起来有点吓人。当然能够和子类共享的类变量在某些时候是有用的。但是大多时候我们需要的是类实例变量(慎用类变量 – 实例变量靠谱量又足),而不是这样的类变量。 所以用类变量之前要考虑清楚自己要做什么。

标签 class_variable, 继承, 类变量, 实例变量, inheritance

Avatar
natsuki 7 年多 前

class A里面是@@count ?

Avatar
hooopo 7 年多 前

是的 编辑器的语法高亮的bug,把@@给变成了@,真坑爹啊

(使用BBCodeTextileGist)