Kann mir jemand etwas über den Unterschied zwischen Klassenvariablen und Klasseninstanzvariablen erzählen?
Kann mir jemand etwas über den Unterschied zwischen Klassenvariablen und Klasseninstanzvariablen erzählen?
Eine Klassenvariable ( @@
) wird von der Klasse und allen ihren Nachkommen gemeinsam genutzt. Eine Klasseninstanzvariable ( @
) wird von den Nachkommen der Klasse nicht gemeinsam genutzt.
Klassenvariable ( @@
)
Lassen Sie uns eine Klasse Foo mit einer Klassenvariablen @@i
und Accessoren zum Lesen und Schreiben haben @@i
:
class Foo
@@i = 1
def self.i
@@i
end
def self.i=(value)
@@i = value
end
end
Und eine abgeleitete Klasse:
class Bar < Foo
end
Wir sehen, dass Foo und Bar den gleichen Wert haben für @@i
:
p Foo.i # => 1
p Bar.i # => 1
Und das Ändern @@i
in einem ändert es in beiden:
Bar.i = 2
p Foo.i # => 2
p Bar.i # => 2
Klasseninstanzvariable ( @
)
@i
Erstellen wir eine einfache Klasse mit einer Klasseninstanzvariablen und Accessoren zum Lesen und Schreiben @i
:
class Foo
@i = 1
def self.i
@i
end
def self.i=(value)
@i = value
end
end
Und eine abgeleitete Klasse:
class Bar < Foo
end
Wir sehen, dass Bar zwar die Accessoren für erbt @i
, sich aber nicht @i
selbst erbt :
p Foo.i # => 1
p Bar.i # => nil
Wir können Bar's setzen, @i
ohne Foo's zu beeinflussen @i
:
Bar.i = 2
p Foo.i # => 1
p Bar.i # => 2
Zuerst müssen Sie verstehen, dass Klassen auch Instanzen sind - Instanzen der
Class
Klasse.Sobald Sie das verstanden haben, können Sie verstehen, dass einer Klasse Instanzvariablen zugeordnet werden können, genau wie es einem regulären Objekt (sprich: Nicht-Klasse) möglich ist.
Beachten Sie, dass eine Instanzvariable ein
Hello
völlig unabhängig von einer Instanzvariablen in einer Instanz von ist und sich von dieser unterscheidetHello
Eine Klassenvariable ist andererseits eine Art Kombination der beiden oben genannten, da sie auf sich
Hello
selbst und ihre Instanzen sowie auf UnterklassenHello
und deren Instanzen zugänglich ist :Viele Leute sagen,
class variables
wegen des seltsamen Verhaltens oben zu vermeiden , und empfehlen die Verwendung vonclass instance variables
stattdessen.quelle
Außerdem möchte ich hinzufügen, dass Sie
@@
von jeder Instanz der Klasse aus Zugriff auf die Klassenvariable ( ) erhalten könnenSie können jedoch nicht dasselbe für die Klasseninstanzvariable (
@
) tunquelle
Foo.i
, aber wie können Sie dasselbe für jede Instanz dieser Klasse wie tunFoo.new.i
?#class
. Ich persönlich denke, dass#class
Verwendungen, wenn sie auf etwas aufgerufen werden, aberself
Code-Gerüche sind. Sie können sogar noch einen Schritt weiter gehen und die Instanz Accessoren implementiereni
undi=
dass die Delegierten ihre#class
Äquivalente, wobei in diesem Fall die Sie tun könnenFoo.new.i
. Ich empfehle dies nicht, da dadurch eine verwirrende Oberfläche entsteht, die darauf hindeutet, dass Sie ein Objektmitglied ändern.