1

您可以创建类的实例变量并将其访问器定义为该类的单例方法。但是类变量的@@var行为很奇怪,尤其是在继承时。它有什么用例吗?

4

2 回答 2

4

我将您所说的奇怪解释为类变量在每个类之间没有不同但在类的继承层次结构之间共享这一事实。

正如您在 Jörg W Mittag 对这个问题的回答中所指出的那样,如果您希望一个变量与一个类一致但在类之外有所不同,那么您可以在该类上使用一个类实例变量。这意味着,如果有任何理由存在,类变量的行为应该与它不同。并且类变量确实在继承层次结构中的类之间共享。

class A
  @@foo = 3
end
class B < A
  puts @@foo
end
# => 3

当您想要共享层次结构中的类共有的东西时,它可能很有用。例如,假设您在一个类中有一些特性将在继承该类的类中使用。假设该特性依赖于一个参数,并且您希望该参数更改在继承该特性的类之间保持一致。然后,类变量将很有用。

例如,假设你有这个方法:

class Array
  def join_with_delimiter
    join(@@delimiter)
  end
end
class A < Array; end

通过设置@@delimiter一次,您可以期望在Array和之间保持一致的行为A

class Array; @@delimiter = "*" end
Array.new([:a, :b, :c]).join_with_delimiter # => "a*b*c"
A.new([:a, :b, :c]).join_with_delimiter # => "a*b*c"

class A; @@delimiter = "#" end
Array.new([:a, :b, :c]).join_with_delimiter # => "a#b#c"
A.new([:a, :b, :c]).join_with_delimiter # => "a#b#c"

如果您使用类实例变量执行此操作,您将不会获得一致的行为:

class Array
  def self.delimiter; @delimiter end
  def join_with_delimiter
    join(self.class.delimiter)
  end
end
class A < Array; end

class Array; @delimiter = "*" end
Array.new([:a, :b, :c]).join_with_delimiter # => "a*b*c"
A.new([:a, :b, :c]).join_with_delimiter # => "abc"

class A; @delimiter = "#" end
Array.new([:a, :b, :c]).join_with_delimiter # => "a*b*c"
A.new([:a, :b, :c]).join_with_delimiter # => "a#b#c"
于 2013-01-06T07:52:13.667 回答
0

类变量用于将值传递给类中的不同方法。

于 2013-01-06T07:15:21.850 回答