2010-01-18 14 views
22

रूबी क्लास-इंस्टेंस सामान मुझे सिरदर्द दे रहा है। मैं इस दी समझ ...रूबी क्लास वेरिएबल्स

class Foo 
    @var = 'bar' 
end 

... कि @var बनाई वर्ग के उदाहरण पर एक चर रहा है।

लेकिन मैं उप-वर्ग अतिरंजित वर्ग चर कैसे बना सकता हूं?

class Fish: 
var = 'fish' 
def v(self): 
    return self.var 

class Trout(Fish): 
    var = 'trout' 

class Salmon(Fish): 
    var = 'salmon' 

print Trout().v() 
print Salmon().v() 

कौन सा आउटपुट:

trout 
salmon 

मैं रूबी में ऐसा ही करते कैसे हैं

यहाँ मैं क्या अजगर में करना होगा का एक उदाहरण है?

+1

नहीं करना चाहिए ' टी कोड के पहले ब्लॉक में @@ var हो? – Jean

+0

मैं डेविड ब्लैक द्वारा "द वेल-ग्राउंडेड रूबीस्ट" (http://manning.com/black2/) पढ़ रहा हूं। वह इस क्षेत्र में सभी बारीकियों को समझाते हुए एक महान काम करता है –

+1

जीन: नहीं। अगर मैंने '@@ var' का उपयोग किया तो उप-वर्ग अभिभावक वर्गों को ओवरराइड कर देगा। होबोडेव का लिंक देखें। विशेष रूप से उदाहरण में '2' कैसे ओवरराइड किया जाता है। –

उत्तर

8

@var ऊपर उल्लेख किया वर्ग उदाहरण चर, जो उदाहरण चर से अलग है कहा जाता है ... diff को देखने के लिए इस सवाल का जवाब here पढ़ें।

class Fish 
    def initialize 
    @var = 'fish' 
    end 

    def v 
    @var 
    end 
end 

class Trout < Fish 
    def initialize 
    @var = 'trout' 
    end 
end 

class Salmon < Fish 
    def initialize 
    @var = 'salmon' 
    end 
end 

puts Trout.new.v 
puts Salmon.new.v 
+0

यह वास्तव में नहीं है, क्योंकि जब भी आप उप-वर्गीकरण करते हैं तो आपको प्रारंभिकरण को ओवरराइड करना होगा। जो बहुत उपयोगी नहीं है। शुरुआती में कुछ कोड शामिल करने के लिए मेरे उदाहरण में यह बेहतर हो सकता है। –

21

विपरीत @ khelll का जवाब करने के लिए, इस उदाहरण चर का उपयोग करता है कक्षा वस्तुओं पर:

class Fish 
    # an instance variable of this Class object 
    @var = 'fish' 

    # the "getter" 
    def self.v 
    @var 
    end 

    # the "setter" 
    def self.v=(a_fish) 
    @var = a_fish 
    end 
end 

class Trout < Fish 
    self.v = 'trout' 
end 

class Salmon < Fish 
    self.v = 'salmon' 
end 

p Trout.v # => "trout" 
p Salmon.v # => "salmon" 

संपादित करें:

वैसे भी इस बराबर रूबी कोड है उदाहरणों देने के लिए पढ़ा कक्षा के आवृत्ति चर तक पहुंच:

class Fish 
    def type_of_fish 
    self.class.v 
    end 
end 

p Trout.new.type_of_fish # => "trout" 
p Salmon.new.type_of_fish # => "salmon" 
+0

नहीं, बिल्कुल नहीं। आप अंत में एक trout.new या सामन नहीं कर रहे हैं। नया। आप कक्षा का उपयोग कर रहे हैं। मैं कक्षा चर प्राप्त करने के लिए * आवृत्ति * चाहता हूँ। –

+0

@ डॉक्टर - अभी के बारे में कैसे? –

+0

यूप। मुझे लगता है कि यह अब कार्यात्मक रूप से equiv है। मैंने जवाब दिया। आप बस एक्सेसर्स मैन्युअल रूप से लिख रहे हैं। –

2

जावा कोडर द्वारा रूबी में आने वाली यह एक आम गलती है, और बड़े वैचारिक कूदों में से एक को मुझे अपना सिर मिलना पड़ा। सबसे पहले यह अजीब लगता है, लेकिन यह वास्तव में रूबी के कूलर पहलुओं में से एक है - सभी कोड कक्षा परिभाषाओं सहित निष्पादन योग्य है।

तो, विधियों के अंदर आवृत्ति चर घोषित किया जाना चाहिए। इसे 'आत्म' का मूल्यांकन कैसे किया जाता है इसके साथ करना है। 'स्वयं' वर्तमान वस्तु है। दुभाषिया 'स्वयं' में पहली विधि कॉल और वैरिएबल संदर्भ देखने देगा:

class Fish 
    @var = "foo" # here 'self' == Fish, the constant which contains the class object 
    def foo 
     # do foo 
    end 
end 

fish = Fish.new 
fish.foo # here 'self' == fish, an instance of Fish 

एक वर्ग परिभाषा में, 'स्वयं' वर्ग वस्तु परिभाषित किया जा रहा है, तो एक वर्ग परिभाषा के दायरे में कोई संदर्भ का उल्लेख होगा होने के लिए सेट कर दिया जाता उस वर्ग वस्तु, इस मामले में मछली।

जब मछली के उदाहरण पर एक विधि कहा जाता है, हालांकि, स्वयं को कॉल का रिसीवर, मछली का विशेष उदाहरण माना जाता है। तो एक विधि परिभाषा के बाहर, स्वयं कक्षा वस्तु है। एक विधि के अंदर, स्वयं रिसीवर का उदाहरण है। यही कारण है कि एक विधि परिभाषा के बाहर @var जावा में स्थिर चर की तरह है, और एक विधि परिभाषा के अंदर @var एक आवृत्ति चर है। - कोई इनिशियलाइज़ ओवरराइड करने के लिए की जरूरत

class Fish 
    class << self 
    attr_accessor :var 
    end 

    @var = 'fish' 
    def v 
    self.class.var 
    end 
end 

class Trout < Fish 
    @var = 'trout' 
end 

class Salmon < Fish 
    @var = 'salmon' 
end 

puts (Trout.new).v # => trout 
puts (Salmon.new).v # => salmon 

सूचना उपवर्गीकरण केवल एक @var जोड़ने की आवश्यकता है कि:

+0

टाइपो: 'fish.foo'' fish.var' होना चाहिए –

+0

असल में, नहीं। मैंने 'foo' को परिभाषित नहीं किया था, लेकिन मुद्दा यह था कि रूबी दुभाषिया को कॉल के प्राप्तकर्ता के रूप में 'मछली' दिखाई देगी और संदर्भ को हल करने के लिए 'स्वयं' को 'मछली' पर सेट किया जाएगा। हालांकि मैंने स्पष्टता के लिए foo विधि जोड़ा है। कॉलिंग 'fish.var' एक NoMethodError फेंक देगा। –

+0

आह। मेरी गलती। इसे समझाने के लिए धन्यवाद। –

4

यहाँ संस्करण मैं hobodave के लिंक का उपयोग कर पता लगाना समाप्त हो गया है।

1

एक एक समस्या है: आप @var ओवरराइड कर सकते हैं: .v # => शार्क
Salmon.var = 'शार्क' @var तो
पुट (Salmon.new) को पार कर जाएगी,

संबंधित मुद्दे