Adakah yang bisa memberi tahu saya tentang perbedaan antara variabel kelas dan variabel contoh kelas?
91
Adakah yang bisa memberi tahu saya tentang perbedaan antara variabel kelas dan variabel contoh kelas?
Variabel kelas ( @@
) dibagikan di antara kelas dan semua turunannya. Variabel instance kelas ( @
) tidak dibagikan oleh turunan kelas.
Variabel kelas ( @@
)
Mari kita memiliki kelas Foo dengan variabel kelas @@i
, dan pengakses untuk membaca dan menulis @@i
:
class Foo
@@i = 1
def self.i
@@i
end
def self.i=(value)
@@i = value
end
end
Dan kelas turunan:
class Bar < Foo
end
Kami melihat bahwa Foo dan Bar memiliki nilai yang sama untuk @@i
:
p Foo.i # => 1
p Bar.i # => 1
Dan mengubah @@i
satu perubahan di keduanya:
Bar.i = 2
p Foo.i # => 2
p Bar.i # => 2
Variabel instance kelas ( @
)
Mari buat kelas sederhana dengan variabel instance kelas @i
dan aksesor untuk membaca dan menulis @i
:
class Foo
@i = 1
def self.i
@i
end
def self.i=(value)
@i = value
end
end
Dan kelas turunan:
class Bar < Foo
end
Kita melihat bahwa meskipun Bar mewarisi aksesornya @i
, ia tidak mewarisi @i
dirinya sendiri:
p Foo.i # => 1
p Bar.i # => nil
Kita dapat mengatur Bar @i
tanpa mempengaruhi Foo @i
:
Bar.i = 2
p Foo.i # => 1
p Bar.i # => 2
Pertama, Anda harus memahami bahwa kelas juga merupakan instance - instance
Class
kelas.Setelah Anda memahaminya, Anda dapat memahami bahwa kelas dapat memiliki variabel instan yang terkait dengannya seperti halnya objek biasa (baca: non-kelas).
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!"
Perhatikan bahwa variabel contoh pada
Hello
sama sekali tidak berhubungan dengan dan berbeda dari variabel contoh pada sebuah contoh dariHello
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!"
Sebuah variabel kelas di sisi lain adalah semacam kombinasi di atas dua, karena dapat diakses pada
Hello
dirinya sendiri dan contoh nya, serta pada subclass dariHello
dan contoh mereka: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!"
Banyak orang mengatakan untuk menghindari
class variables
karena perilaku aneh di atas, dan merekomendasikan penggunaanclass instance variables
sebagai gantinya.sumber
Juga saya ingin menambahkan bahwa Anda bisa mendapatkan akses ke variabel kelas (
@@
) dari setiap contoh kelasclass 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
Tetapi Anda tidak dapat melakukan hal yang sama untuk variabel instance kelas (
@
)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
sumber
Foo.i
, tetapi bagaimana Anda dapat melakukan hal yang sama untuk setiap contoh dari kelas iniFoo.new.i
?#class
. Saya pribadi berpikir#class
penggunaan ketika dipanggil apa pun kecualiself
bau kode sekalipun. Anda bahkan dapat melangkah lebih jauh dan mengimplementasikan pengakses instancei
dani=
delegasi itu ke#class
padanannya, dalam hal ini Anda dapat melakukannyaFoo.new.i
. Saya tidak menyarankan melakukan itu karena itu membuat antarmuka yang membingungkan, menyarankan Anda memodifikasi anggota objek.