Herkes bana sınıf değişkenleri ile sınıf örneği değişkenleri arasındaki farkı söyleyebilir mi?
Yanıtlar:
Bir sınıf değişkeni ( @@
), sınıf ve onun tüm soyundan gelenler arasında paylaşılır. Bir sınıf örneği değişkeni ( @
), sınıfın soyundan gelenler tarafından paylaşılmaz.
Sınıf değişkeni ( @@
)
Sınıf değişkenine sahip bir sınıf Foo @@i
ve okuma ve yazma için erişimciler edelim @@i
:
class Foo
@@i = 1
def self.i
@@i
end
def self.i=(value)
@@i = value
end
end
Ve türetilmiş bir sınıf:
class Bar < Foo
end
Foo ve Bar'ın aşağıdakiler için aynı değere sahip olduğunu görüyoruz @@i
:
p Foo.i # => 1
p Bar.i # => 1
Ve @@i
birinde değiştirmek onu ikisinde de değiştirir:
Bar.i = 2
p Foo.i # => 2
p Bar.i # => 2
Sınıf örneği değişkeni ( @
)
Bir sınıf örnek değişkeni @i
ve okuma ve yazma için erişimcilerle basit bir sınıf yapalım @i
:
class Foo
@i = 1
def self.i
@i
end
def self.i=(value)
@i = value
end
end
Ve türetilmiş bir sınıf:
class Bar < Foo
end
Bar'ın erişimcileri miras almasına rağmen @i
, @i
kendisini miras almadığını görüyoruz :
p Foo.i # => 1
p Bar.i # => nil
@i
Foo'ları etkilemeden Bar'ı ayarlayabiliriz @i
:
Bar.i = 2
p Foo.i # => 1
p Bar.i # => 2
Öncelikle, sınıfların da örnek olduğunu anlamalısınız - Class
sınıfın örnekleri .
Bunu anladıktan sonra, bir sınıfın, normal (okuma: sınıf dışı) bir nesnenin yapabildiği gibi kendisiyle ilişkilendirilmiş örnek değişkenlerine sahip olabileceğini anlayabilirsiniz.
Hello = Class.new
# setting an instance variable on the Hello class
Hello.instance_variable_set(:@var, "good morning!")
# getting an instance variable on the Hello class
Hello.instance_variable_get(:@var) #=> "good morning!"
Bir örneği değişken unutmayın Hello
, bir de bir örnek değişkeni tamamen ilişkisiz ve farklı örnek arasındaHello
hello = Hello.new
# setting an instance variable on an instance of Hello
hello.instance_variable_set(:@var, :"bad evening!")
# getting an instance variable on an instance of Hello
hello.instance_variable_get(:@var) #=> "bad evening!")
# see that it's distinct from @var on Hello
Hello.instance_variable_get(:@var) #=> "good morning!"
Öte yandan bir sınıf değişkeni , Hello
kendisinde ve örneklerinde ve ayrıca alt sınıflarında ve örneklerinde erişilebildiği için yukarıdaki ikisinin bir tür kombinasyonudur Hello
:
HelloChild = Class.new(Hello)
Hello.class_variable_set(:@@class_var, "strange day!")
hello = Hello.new
hello_child = HelloChild.new
Hello.class_variable_get(:@@class_var) #=> "strange day!"
HelloChild.class_variable_get(:@@class_var) #=> "strange day!"
hello.singleton_class.class_variable_get(:@@class_var) #=> "strange day!"
hello_child.singleton_class.class_variable_get(:@@class_Var) #=> "strange day!"
Birçok insan class variables
yukarıdaki garip davranış nedeniyle kaçınılması gerektiğini söylüyor ve class instance variables
bunun yerine kullanılmasını tavsiye ediyor .
Ayrıca, sınıfın @@
herhangi bir örneğinden sınıf değişkenine ( ) erişebileceğinizi de eklemek istiyorum.
class Foo
def set_name
@@name = 'Nik'
end
def get_name
@@name
end
end
a = Foo.new
a.set_name
p a.get_name # => Nik
b = Foo.new
p b.get_name # => Nik
Ancak aynı şeyi sınıf örneği değişkeni ( @
) için yapamazsınız
class Foo
def set_name
@name = 'Nik'
end
def get_name
@name
end
end
a = Foo.new
a.set_name
p a.get_name # => Nik
b = Foo.new
p b.get_name # => nil
Foo.i
, ancak bu sınıfın her örneği için aynısını nasıl yapabilirsiniz Foo.new.i
?
#class
. Kişisel #class
olarak herhangi bir şey çağrıldığında kullanım olduğunu düşünüyorum ama self
kod kokuyor. Hatta bir adım daha ileri gidebilir ve örnek erişimcileri uygulayabilir i
ve i=
bu temsilciyi #class
eşdeğerlerine atayabilirsiniz, bu durumda yapabilirsiniz Foo.new.i
. Bunu, bir nesne üyesini değiştirdiğinizi düşündüren kafa karıştırıcı bir arayüz oluşturduğu için yapmanızı önermiyorum.