2013-02-17 18 views
6

मैं अच्छी तरह से ग्राउंडेड रूबीस्ट पढ़ रहा हूं और यह उल्लेख करता है कि कक्षा को अपनी सुपर क्लास के उदाहरण विधियों को कैसे प्राप्त किया जाता है ताकि कक्षा की वस्तुएं उन उदाहरण विधियों को कॉल कर सकें। यहाँ एक उदाहरण है:रूबी विरासत को समझना

class C 
    def run_instance_method 
    puts "This is an instance method." 
    end 
    def C.run_class_method 
    puts "This is a class method." 
    end 
end 

class D < C 
end 

मैं क्या पढ़ा है, यह हमेशा उस वर्ग डी क्लास सी का सिर्फ उदाहरण तरीकों (इस स्थिति में, सी :: run_class_method द्वारा विरासत में मिला नहीं किया जाएगा वारिस होगा वर्णित किया गया है के आधार पर डी)। हालांकि, इसके बाद के संस्करण कोड चलाने के बाद, मैं ध्यान दें कि:

D.run_class_method # => "This is a class method." 

यहाँ क्यों यह हो रहा है के रूप में मेरा अनुमान है और मुझे पता है कि अगर यह सही समझ है तो कृपया। यदि कक्षा डी का एक उदाहरण डी है और आप d.run_instance_method को चलाने का प्रयास करते हैं, तो वह ऑब्जेक्ट अपना विधि-लुकअप पथ खोजेगा और देखें कि क्या यह विधि इसके सिंगलटन क्लास, अपनी कक्षा में या इसके सुपरक्लास में परिभाषित की गई है। चूंकि run_instance_method को कक्षा सी में परिभाषित किया गया है, इसलिए कोई समस्या नहीं होगी और run_instance_method को कॉल किया जाएगा। क्लास ऑब्जेक्ट डी (जो सी और ऑब्जेक्ट का उप-वर्ग है) के लिए, यदि D.run_class_method कहा जाता है, तो यह फिर से डी क्लास ऑब्जेक्ट के लिए विधि लुकअप पथ की जांच करेगा। दोबारा, रुबी इसे क्लास ऑब्जेक्ट सी में मिलेगा।

क्या यह तर्क सटीक है?

उत्तर

5

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

एक सिफारिश के रूप में: जब एक स्पष्ट रिसीवर के साथ कक्षा विधि का आह्वान करते हैं, तो आपको विरासत पर भरोसा करना चाहिए। क्लास विधि को कक्षा के माध्यम से हमेशा आमंत्रित करें जो इसे परिभाषित करता है। अन्यथा, यह किसी ऐसे व्यक्ति के लिए बहुत मुश्किल होगा जो कक्षा कोड को परिभाषित करने वाले अभिभावक वर्ग को खोजने के लिए आपके कोड पर निर्भर करता है।

अपनी मूल धारणा पर वापस संदर्भित करना: उप-वर्ग से कक्षा विधि का आविष्कार संभव है क्योंकि कक्षा विधियां eigenclass के उदाहरण विधियां हैं।

class C 
    # instance methods goes here 
    class << self # open the eigenclass 
    # class methods go here as instance methods of the eigenclass 
    end 
end 

सामान्य में, यह स्पष्ट रूप से eigenclass खोले बिना व्यक्ति सिंगलटन तरीके के रूप में वर्ग के तरीकों को परिभाषित करने के लिए स्पष्ट है।

एक स्पष्ट विवरण के लिए डेविड फ्लानागन और यूकिहिरो मैट्सुमोटो द्वारा The Ruby Programming Language पढ़ा विवरण के लिए

+0

धन्यवाद। यदि आप इस स्पष्टीकरण के साथ गलत हैं तो क्या आप मुझे सही कर सकते हैं: मूल रूप से, सभी वर्ग विधियां उनके ईजेनक्लास में उदाहरण विधियों के रूप में रहते हैं। यदि कक्षा डी को अपने सुपरक्लास क्लास सी से विरासत में मिला है, तो क्लास डी के ईजेनक्लास को कक्षा सी के ईजेनक्लास से भी विरासत में मिला है। और इस कारण से क्लास ऑब्जेक्ट डी कॉल कर सकता है .run_class_method। क्या यह सही है? – wmock

+1

बिल्कुल! जब रूबी एक विधि आमंत्रण अभिव्यक्ति का मूल्यांकन करता है तो पहले यह पता लगाना होगा कि किस विधि को लागू करने की आवश्यकता है। इसे 'विधि लुकअप' कहा जाता है: स्वयं वर्ग में विधि परिभाषा के लिए पहली खोज, यदि कोई विधि नहीं मिलती है, तो श्रृंखला मूल तक कक्षा अभिभावक आदि में खोजें। –

2

बिल्कुल बिल्कुल नहीं। यहां एक और अवधारणा छिपी हुई है, जिसे metaclass या eigenclass कहा जाता है। कक्षा विधि eigenclass से विरासत में मिला है। इसके बारे में अधिक जानकारी के लिए Ruby Hacking Guide देखें। (यदि आप उन्हें सभी पढ़ना नहीं चाहते हैं तो बस पृष्ठ में "कक्षा विधियों" की खोज करें।)

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