答案部分正确,因为@@实际上是一个类变量,每个类层次结构都有一个,这意味着它由一个类、它的实例和其子类及其实例共享。
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类只有一个相同的@@变量,所有这些类和实例方法都引用相同的变量。
还有一种定义类变量的方法是在类对象上定义(记住每个类实际上是某个东西的实例,它实际上是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 或 Graduate 类的特定实例的实例变量。因此,虽然其他答案正确地说明了只使用单个 @ 表示的 @myvariable 总是实例变量,但这并不一定意味着它不是该类所有实例共享的单个变量。
self
方法内部使用@
),而不是类变量(即@@
)。请查看下面的答案,了解其中的原因。 - WattsInABox