वर्ग चर और वर्ग उदाहरण चर के बीच अंतर?


जवाबों:


151

एक वर्ग चर ( @@) वर्ग और उसके सभी वंशों के बीच साझा किया जाता है। एक वर्ग उदाहरण चर ( @) वर्ग के वंशजों द्वारा साझा नहीं किया जाता है।


कक्षा चर ( @@)

चलो एक वर्ग के साथ एक वर्ग फू है @@i, और पढ़ने और लिखने के लिए accessors @@i:

class Foo

  @@i = 1

  def self.i
    @@i
  end

  def self.i=(value)
    @@i = value
  end

end

और एक व्युत्पन्न वर्ग:

class Bar < Foo
end

हम देखते हैं कि फू और बार के लिए समान मूल्य है @@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

हम देखते हैं कि यद्यपि बार के लिए अभिगमकर्ता को विरासत में मिला है @i, यह @iस्वयं को विरासत में नहीं मिला है:

p Foo.i    # => 1
p Bar.i    # => nil

हम @iफू को प्रभावित किए बिना बार को सेट कर सकते हैं @i:

Bar.i = 2
p Foo.i    # => 1
p Bar.i    # => 2

1
क्लास के तरीकों का उपयोग करके इंस्टेंस वेरिएबल्स क्यों लौटाते हैं? क्या आप अक्सर इस स्थिति में भागते हैं?
सेकोमो

1
@sekmo इन उदाहरणों में एक्सेसर्स या तो क्लास इंस्टेंस वैरिएबल लौटाते हैं , जो क्लास, या क्लास वेरिएबल से संबंधित होते हैं, जो क्लास पदानुक्रम से संबंधित होते हैं। वे सादे उदाहरण चर नहीं लौटाते हैं जो वर्ग के उदाहरण हैं। शब्द "उदाहरण चर," "वर्ग उदाहरण चर," और "वर्ग चर" काफी भ्रामक हैं, वे नहीं हैं?
वेन कॉनराड

72

सबसे पहले आपको समझना चाहिए कि कक्षाएं भी उदाहरण हैं - उदाहरण 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इसके बजाय इसके उपयोग की सलाह देते हैं ।


2
+1 सुपर स्पष्टीकरण! यह कुछ ऐसा है जो रूबी के लिए हर प्रोग्रामर को पचाना चाहिए।
टॉमजेड

0

इसके अलावा, मैं यह जोड़ना चाहता हूं कि आप कक्षा के @@किसी भी उदाहरण से वर्ग चर ( ) तक पहुंच प्राप्त कर सकते हैं

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

-1: यह गलत है: वर्ग उदाहरण चर को उस वर्ग के हर उदाहरण से एक्सेस किया जा सकता है (बशर्ते कि एक्सेसर्स मौजूद हों)। इसके अलावा, आपका उदाहरण नियमित उदाहरण चर दिखाता है, वर्ग उदाहरण चर नहीं। क्लास इंस्टेंस वेरिएबल्स को तरीकों से बाहर घोषित किया जाता है, और रेगुलर इंस्टेंस वेरिएबल और क्लास वेरिएबल दोनों से फंडामेंटल रूप से अलग होते हैं।
पेलेमिस्टर

आप उस वर्ग के हर उदाहरण से वर्ग उदाहरण चर तक कैसे पहुंच सकते हैं?
इवान रॉस

क्या आपने वेन कॉनराड का जवाब पढ़ा है? वह सचमुच इसकी व्याख्या करता है। stackoverflow.com/a/3803089/439592
पेलमिस्टर

मुझे पता है कि आप कक्षा के तरीकों से पहुंच प्राप्त कर सकते हैं Foo.i, लेकिन आप इस वर्ग के हर उदाहरण के लिए ऐसा कैसे कर सकते हैं Foo.new.i?
इवान रॉस

का उपयोग करके #class। मुझे व्यक्तिगत रूप से लगता है कि #classजब किसी भी चीज़ पर कॉल किया जाता है, लेकिन selfकोड की गंध होती है। तुम भी एक कदम आगे जाने के लिए और उदाहरण accessors लागू कर सकते हैं iऔर i=उनके लिए है कि प्रतिनिधि #classसमकक्ष, जिस स्थिति में आप क्या कर सकते हैं Foo.new.i। मैं ऐसा करने की अनुशंसा नहीं करता क्योंकि यह एक भ्रमित इंटरफ़ेस बनाता है, यह सुझाव देता है कि आप एक वस्तु सदस्य को संशोधित कर रहे हैं।
पेलेमिस्टर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.