ใครช่วยบอกฉันเกี่ยวกับความแตกต่างระหว่างตัวแปรคลาสและตัวแปรอินสแตนซ์คลาสได้ไหม
ใครช่วยบอกฉันเกี่ยวกับความแตกต่างระหว่างตัวแปรคลาสและตัวแปรอินสแตนซ์คลาสได้ไหม
คำตอบ:
ตัวแปรคลาส ( @@
) ถูกแบ่งใช้ระหว่างคลาสและลูกหลานทั้งหมด ตัวแปรอินสแตนซ์คลาส ( @
) ไม่ได้แบ่งใช้โดยลูกหลานของคลาส
ตัวแปรคลาส ( @@
)
มามีคลาส Foo พร้อมตัวแปรคลาส@@i
และ accessors สำหรับการอ่านและเขียน@@i
:
class Foo
@@i = 1
def self.i
@@i
end
def self.i=(value)
@@i = value
end
end
และคลาสที่ได้รับ:
class Bar < Foo
end
เราเห็นว่า Foo และ Bar มีค่าเท่ากันสำหรับ@@i
:
p Foo.i # => 1
p Bar.i # => 1
และการเปลี่ยนแปลง@@i
ในครั้งเดียวการเปลี่ยนแปลงในทั้งสอง:
Bar.i = 2
p Foo.i # => 2
p Bar.i # => 2
ตัวแปรอินสแตนซ์คลาส ( @
)
มาสร้างคลาสง่ายๆด้วยตัวแปรอินสแตนซ์คลาส@i
และตัวเข้าถึงสำหรับการอ่านและเขียน@i
:
class Foo
@i = 1
def self.i
@i
end
def self.i=(value)
@i = value
end
end
และคลาสที่ได้รับ:
class Bar < Foo
end
เราเห็นว่าแม้ว่า Bar จะสืบทอด accessors สำหรับ@i
แต่ก็ไม่ได้สืบทอด@i
ตัวเอง:
p Foo.i # => 1
p Bar.i # => nil
เราสามารถตั้งค่า Bar ได้@i
โดยไม่กระทบกับ Foo @i
:
Bar.i = 2
p Foo.i # => 1
p Bar.i # => 2
ก่อนอื่นคุณต้องเข้าใจว่าคลาสก็เป็นอินสแตนซ์เช่นกัน - อินสแตนซ์ของClass
คลาส
เมื่อคุณเข้าใจแล้วคุณจะเข้าใจว่าคลาสสามารถมีตัวแปรอินสแตนซ์ที่เชื่อมโยงกับมันได้เช่นเดียวกับที่ออบเจ็กต์ปกติ (อ่าน: ไม่ใช่คลาส) สามารถทำได้
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!"
โปรดทราบว่าตัวแปรอินสแตนซ์บนHello
ไม่เกี่ยวข้องโดยสิ้นเชิงและแตกต่างจากตัวแปรอินสแตนซ์บนอินสแตนซ์ของHello
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!"
ตัวแปรระดับบนมืออื่น ๆ เป็นชนิดของการรวมกันของสองข้างต้นเป็นมันสามารถเข้าถึงได้บนHello
ตัวเองและกรณีของตนเช่นเดียวกับคลาสย่อย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!"
หลายคนบอกว่าให้หลีกเลี่ยงclass variables
เนื่องจากพฤติกรรมแปลก ๆ ข้างต้นและแนะนำให้ใช้class instance variables
แทน
นอกจากนี้ฉันต้องการเพิ่มว่าคุณสามารถเข้าถึงตัวแปรคลาส ( @@
) จากอินสแตนซ์ของคลาสใดก็ได้
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
แต่คุณไม่สามารถทำเช่นเดียวกันกับตัวแปรอินสแตนซ์คลาส ( @
)
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
แต่คุณจะทำเช่นเดียวกันกับทุกอินสแตนซ์ของคลาสนี้ได้Foo.new.i
อย่างไร
#class
. โดยส่วนตัวฉันคิดว่าการ#class
ใช้งานเมื่อถูกเรียกใช้อะไรก็ได้ แต่self
เป็นกลิ่นรหัส คุณยังสามารถไปขั้นตอนต่อไปและดำเนินการเช่น accessors i
และi=
ผู้ร่วมประชุมที่พวกเขาเทียบเท่าซึ่งในกรณีที่คุณสามารถทำได้#class
Foo.new.i
ฉันไม่แนะนำให้ทำเช่นนั้นเนื่องจากมันสร้างอินเทอร์เฟซที่สับสนแนะนำว่าคุณกำลังแก้ไขสมาชิกออบเจ็กต์