答案是部分正确的,因为 @@ 实际上是一个类变量,它是每个类层次结构的,这意味着它由一个类、它的实例及其后代类及其实例共享。
class Person
@@people = []
def initialize
@@people << self
end
def self.people
@@people
end
end
class Student < Person
end
class Graduate < Student
end
Person.new
Student.new
puts Graduate.people
这将输出
#<Person:0x007fa70fa24870>
#<Student:0x007fa70fa24848>
因此,对于 Person、Student 和 Graduate 类只有一个相同的 @@variable,并且这些类的所有类和实例方法都引用同一个变量。
还有另一种定义在类对象上定义的类变量的方法(请记住,每个类实际上是一个实例,实际上是 Class 类,但这是另一回事)。您使用@ 表示法而不是@@,但您不能从实例方法访问这些变量。您需要有类方法包装器。
class Person
def initialize
self.class.add_person self
end
def self.people
@people
end
def self.add_person instance
@people ||= []
@people << instance
end
end
class Student < Person
end
class Graduate < Student
end
Person.new
Person.new
Student.new
Student.new
Graduate.new
Graduate.new
puts Student.people.join(",")
puts Person.people.join(",")
puts Graduate.people.join(",")
在这里,@people 每个类而不是类层次结构是单个的,因为它实际上是存储在每个类实例上的变量。这是输出:
#<Student:0x007f8e9d2267e8>,#<Student:0x007f8e9d21ff38>
#<Person:0x007f8e9d226158>,#<Person:0x007f8e9d226608>
#<Graduate:0x007f8e9d21fec0>,#<Graduate:0x007f8e9d21fdf8>
一个重要的区别是,您不能直接从实例方法访问这些类变量(或您可以说的类实例变量),因为实例方法中的 @people 将引用 Person 或 Student 或研究生类的特定实例的实例变量.
因此,尽管其他答案正确地指出 @myvariable(带有单个 @ 表示法)始终是一个实例变量,但这并不一定意味着它不是该类的所有实例的单个共享变量。