2012-06-17 10 views
9

इस प्रकार एक वर्ग पदानुक्रम को देखते हुए:अभिभावक वर्ग शुरू करते समय सबक्लास के नए उदाहरण को कैसे वापस करें?

class A 
    def initialize(param) 
    if param == 1 then 
     #initialize and return instance of B 
    else 
     #initialize and return instance of C 
    end 
    end 
end 

class B < A 
end 

class C < A 
end 

यह वास्तव में प्रारंभ और B या C का एक उदाहरण वापस जाने के लिए संभव है जब A आरंभ? अर्थात। my_obj = A.new(param)param के मान के आधार पर के मूल्य के आधार पर B या C का उदाहरण होने के परिणामस्वरूप my_obj होगा।

मेरी USECASE में इसकी केवल क्रम जो उपवर्ग (B या C) का उपयोग करने और माता पिता के वर्ग (A) में जाना जाता है मूल रूप से वास्तव में कभी नहीं किया जाता है। मैंने सोचा कि B या C अपने सामान्य पूर्वजों में यह तय करने के तर्क को स्थानांतरित करना एक अच्छा विचार हो सकता है।

यदि यह संभव नहीं है (या खराब शैली), तो मुझे param और किस वर्ग को प्रारंभ करने का निर्णय रखना चाहिए?

+1

इसी तरह के प्रश्नों का उत्तर पहले दिया गया है।आप जो खोज रहे हैं वह कारखाने के तरीके हैं। Http://stackoverflow.com/questions/1515577/factory-methods-in-ruby पर एक नज़र डालें, मुझे लगता है कि http://stackoverflow.com/a/1515580/1128705 पर उत्तर आपकी आवश्यकताओं के अनुरूप होगा। –

उत्तर

8

आप एक मौलिक OO सिद्धांत यहाँ तोड़ रहे हैं - कक्षाओं के बारे में कुछ भी नहीं पता होना चाहिए उनके उपवर्गों। बेशक, कभी-कभी सिद्धांतों को तोड़ा जाना चाहिए, लेकिन यहां ऐसा करने का कोई स्पष्ट कारण नहीं है।

एक बेहतर वर्ग में एक फैक्ट्री विधि में तत्काल तर्क को स्थानांतरित करना एक बेहतर समाधान है। फैक्ट्री विधि उपरोक्त ए के प्रारंभकर्ता के समान तर्क लेती है, और उपयुक्त वर्ग का एक उदाहरण देता है।

+0

जोर से यह कहने के लिए धन्यवाद। :) मैंने आखिरकार एक अलग मॉड्यूल में एक विधि 'initiate_A' लिखा, जो निर्णय करता है और एक नई वस्तु देता है। –

+0

एक या दो मामले हो सकते हैं जहां यह उचित है। जैसा कि मैंने अपने जवाब में कहा था, क्या होगा यदि आपके पास एक पार्सर क्लास है, उदाहरण के लिए, किसी भाषा के विभिन्न संस्करणों से निपटना होगा? आपके पास एक कन्स्ट्रक्टर हो सकता है जो डेटा के सही संस्करण के लिए दाएं उप-वर्ग का उदाहरण देता है। एचटीएमएल 5 एचटीएमएल एक अच्छा विरासत संबंध नहीं है, मुझे नहीं पता कि क्या है। – Linuxios

+0

हम एक-दूसरे से सहमत हैं - इस सिद्धांत को तोड़ने पर अच्छा कारण हो सकता है। यकीन नहीं है कि मुझे आपका उदाहरण पसंद है, हालांकि, यह सार फैक्ट्री के मामले की तरह लगता है। – ComDubh

3

बात यह है कि initialize का वापसी मूल्य अनदेखा किया जाता है। इस वर्ग की एक खाली उदाहरण देता

  • new तो कॉल initialize वस्तु allocate द्वारा दिया पर, और ऑब्जेक्ट -

    • new एक विशेष वर्ग विधि allocate बुलाया कॉल: यहाँ क्या होता है जब आप कॉल A.new है

    क्या आप क्या करना चाहते करने के लिए, आप new ओवरराइड और यह तुम क्या चाहते हो बनाने की जरूरत है:

    class A 
        def self.new(args*) 
        if(args[0]==1) 
         B.new(*args[1..-1]) 
        else 
         C.new(*args[1..-1]) 
        end 
        end 
    end 
    

    हालांकि विचार करने के लिए कुछ और है। यदि A कभी भी अपने आप पर कभी भी उपयोग नहीं किया जाता है, तो आपको कुछ प्रकार की फैक्ट्री विधि का उपयोग करना चाहिए, या सिर्फ कथन के लिए एक साधारण उपयोग करना चाहिए। उदाहरण:

    def B_or_C(param,args) 
        (param == 1 ? B : C).new(args) 
    end 
    

    डिज़ाइन वास्तव में उस पर निर्भर करता है कि आप उनका उपयोग किस प्रकार कर रहे हैं। जब आप, उदाहरण के लिए, एक वर्ग है कि उदाहरण के लिए कुछ एक से अधिक संस्करण, संभाल करने के लिए इस्तेमाल किया जा सकता है, एचटीएमएल, यदि आप एक मुख्य वर्ग HTMLParser जो new overrode हो सकता था और उसके उपवर्गों के किसी भी वापसी कर सकते हैं: HTML1Parser, HTML2Parser, HTML3Parser, HTML4Parser , और HTML5Parser

    ध्यान दें: आप अनंत पाशन को रोकने के लिए उप-वर्गों में डिफ़ॉल्ट करने के लिए new विधि ओवरराइड करने के लिए है:

    def self.new(args*) 
        obj=allocate 
        obj.send(:initialize, *args) 
        obj 
    end 
    
  • +0

    आपके उत्तर के लिए धन्यवाद। हालांकि, 'ए' में 'self.new' को ओवरराइड करते समय और' एनी (पैरा) 'को कॉल करते समय, मुझे एक त्रुटि मिल रही है:' सिस्टमस्टैक त्रुटि: ढेर स्तर बहुत गहरा '। ऐसा लगता है कि 'एन्यू 'के अंदर' बीन्यू '(या' सीन्यू ') को कॉल करने से अनंत बीओपी का कारण बनता है क्योंकि' बी 'और' सी 'के" कन्स्ट्रक्टर "किसी भी तरह से" कन्स्ट्रक्टर "को बुला रहे हैं 'ए', अर्थात् 'एनी'। –

    +0

    विरासत के कारण –

    +0

    @Torbjoern: संपादित करें देखें। – Linuxios

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