2009-07-07 5 views
10

स्पष्ट होने के लिए, मैं नहीं पूछ रहा हूं कि एकाधिक विरासत अच्छी या बुरी क्यों है। मैंने उस बहस के दोनों तरफ से कई तर्क सुना है।जब एकाधिक विरासत एकमात्र उचित समाधान हो सकता है?

मुझे आश्चर्य है कि सी ++ में किसी प्रकार की डिज़ाइन समस्या या परिदृश्य है जिसमें एकाधिक विरासत या तो कुछ हासिल करने का एकमात्र तरीका है, या कम से कम इस बिंदु पर अन्य सभी विकल्पों पर सबसे इष्टतम तरीका है किसी और चीज पर विचार करने के लिए समझ में नहीं आता है।

जाहिर है, यह प्रश्न उन भाषाओं पर लागू नहीं होता है जो एकाधिक विरासत का समर्थन नहीं करते हैं।

+0

ऐसा ही एक सवाल: http://stackoverflow.com/questions/573913/a-use-for-multiple-inheritance –

उत्तर

10

आप एकाधिक विरासत के बिना policy-based design नहीं कर सकते हैं। इसलिए यदि पॉलिसी-आधारित डिज़ाइन आपकी समस्या का समाधान करने का सबसे शानदार तरीका है, तो इसका मतलब है कि आपको अन्य सभी विकल्पों पर अपनी समस्या का समाधान करने के लिए कई विरासत की आवश्यकता है।

एकाधिक विरासत बहुत उपयोगी हो सकती है अगर इसका दुरुपयोग नहीं किया जाता है (जैसे किसी भी भाषा में)।

+2

इस अर्थ होगा कि नीति आधारित डिजाइन बस एक भाषा में संभव नहीं है जैसे कि जावा, या इसके आसपास काम करने के तरीके हैं? –

+0

असल में, लिंक किया गया आलेख इंगित करता है कि एकाधिक विरासत केवल सबसे आम कार्यान्वयन पैटर्न (कुछ महत्वपूर्ण फायदों के साथ) है, यह बिल्कुल आवश्यक नहीं है। – GalacticCowboy

+0

@ जेफ एल: जावा में 'प्रॉक्सी' कक्षा को वर्कअराउंड के रूप में उपयोग किया जा सकता है। – finnw

5

ऐसी स्थिति है जिसमें आप कक्षा से उत्तराधिकारी होंगे और शायद जावा में एक या दो इंटरफेस लागू करेंगे। यह ऐसा कुछ है जिसे आप सी ++ में एकाधिक विरासत के साथ हल करेंगे।

2

मैं जावा इंटरफेस पर पढ़ता हूं, और इसी तरह, इस प्रश्न के उत्तर के रूप में बेहतर विचार प्राप्त करने के लिए। इंटरफेस के पीछे विचार एक अमूर्त वर्ग बनाना है जो किसी अन्य वर्ग के लिए टेम्पलेट के रूप में कार्य करता है। लाभ, यहां, यह है कि टेम्पलेट को ठोस वर्ग के भीतर जोड़ा जा सकता है। उदाहरण के

जनक वर्ग FoodStore Subclass- Coffeeshop Subclass- बेकरी

इस विरासत पेड़ के साथ

के लिए, एक FoodStore एक बेकरी या एक Coffeeshop लेकिन दोनों नहीं हो सकता है। लेकिन फिर हम स्टारबक्स को क्या कहते हैं?

बेहतर तरीका, IMO-

जनक कक्षा FoodStore इंटरफ़ेस- Coffeeshop इंटरफ़ेस- बेकरी

सार्वजनिक वर्ग स्टारबक्स फैली FoodStore लागू करता coffeeshop, बेकरी {...}

आप करेंगे इसे समझने के लिए जावा का थोड़ा सा पता होना चाहिए, लेकिन इसमें है। इंटरफेस काफी प्राथमिक हैं, आईएमओ।

एक और संगीत के रूप में, शायद इंटरफेस को "खुद को दोहराना न करें" का पालन करने के लिए डिज़ाइन किया गया है। जाहिर है, अब मैं इसका जिक्र करता हूं।

3

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

0

के रूप में अन्य उत्तर को कहा गया है:

  • , "इंटरफेस" के रूप में शुद्ध आभासी आधार वर्ग का उपयोग जावा (http://en.wikipedia.org/wiki/Interface_(Java)) के रूप में, यह एक बहुत ही आम O.O. है सभी ओओ में पैटर्नभाषाओं, न केवल जावा

  • ऐसा करने के लिए पुलिस आधारित डिजाइन

लेकिन यह भी:

  • कई mixins (http://en.wikipedia.org/wiki/Mixin) के साथ एक वर्ग रचना करने के लिए; मैं कोड पुन: उपयोग प्राप्त करने के लिए यह एकाधिक विरासत का एक बहुत अच्छा उपयोग मानता हूं!
3

सी ++ धाराओं एकाधिक वंशानुक्रम का उपयोग करें: istream और ostreamiostream के माता-पिता दोनों कर रहे हैं। चूंकि वे दोनों ios_base से प्राप्त होते हैं, आपके पास हीरा होता है।

यह इस अर्थ में एकमात्र "उचित" समाधान है कि यह मानक पुस्तकालयों के धाराओं के भाग को एल्गोरिदम और संग्रह के समान रेखा लेने के लिए अनुचित होगा। इसलिए ओस्ट्रीम इटरेटर (*) जैसे "बतख-टाइप किए गए" इंटरफ़ेस होने के बजाय बहुरूप रूप से व्यवहार करता है।

जैसे ही आपके पास गतिशील बहुरूपता है, आपको एक ही समय में एक से अधिक इंटरफ़ेस को लागू करने के लिए एकाधिक विरासत की आवश्यकता है।

(*) संभवतः ऐसा इसलिए है क्योंकि कुछ भी एक झटके होगा। उपयोगकर्ताओं को हर जगह टेम्पलेट्स रखने के लिए आपको वास्तविक कार्यों को लिखने में सक्षम होना चाहिए, जो धाराओं में हेरफेर करते हैं। ऐसा इसलिए है क्योंकि "कुछ धाराओं को लिखना आम बात है, मुझे नहीं पता कि रनटाइम तक क्या है", लेकिन कुछ संग्रह में हस्तक्षेप नहीं करना चाहते हैं, मुझे नहीं पता कि रनटाइम तक क्या है "।

1

जब आप भूमिका के बजाए कार्यक्षमता प्राप्त करना चाहते हैं, तो बिंदु boost::noncopyable (अन्य भाषाओं जो जावा और सी # के विपरीत) का समर्थन करते हैं, इसे मिक्सिन) पर कॉल करें।

0

जब आपको दो या दो से अधिक तृतीय-पक्ष वर्ग पदानुक्रमों को गठबंधन करना होगा, जिनमें से प्रत्येक को पदानुक्रम की अपनी बेस क्लास से प्राप्त किया जाना चाहिए, तो एकाधिक विरासत की कमी से आपका कोड जटिल और विचित्र हो जाएगा।

namespace Object_Database { 
    class Object { 
     public: 
     virtual void store() ; 
     virtual void fetch() ; 
    }; 
} 

namespace Reflectives { 
    class Object { 
     public: 
     virtual std::vector<std::string> > membernames(); 
     virtual std::vector<std::string> > methodnames(); 
    }; 
} 

पहले पदानुक्रम उन वस्तुओं जो करने के लिए और एक वस्तु डेटाबेस से श्रृंखलाबद्ध किया जा सकता है बनाने की सुविधा देता है, और की आवश्यकता है कि इस तरह की सभी वस्तुओं वर्ग Object_Database से प्राप्त किया जा :: वस्तु। दूसरा पदानुक्रम उपयोगकर्ताओं को ऑब्जेक्ट्स बनाने देता है जिसे रनटाइम पर उनके सदस्यों के नामों के लिए पूछताछ की जा सकती है, और यह आवश्यक है कि ऐसी सभी वस्तुओं को प्रतिबिंबित :: ऑब्जेक्ट से लिया जाए।

class ReflectivePickle : 
    public Object_Database::Object, 
    public Reflectives::Object { 
    // ... 
    }; 

अन्य समाधान अनुचित हैं:

आप वस्तुओं है कि दोनों क्या कर सकते हैं की आवश्यकता होती है, तो आप सिर्फ लिखने के लिए की जरूरत है।

0

मैं सी ++ में एकाधिक विरासत का उपयोग करता हूं, जब मूल कक्षाएं "इंटरफ़ेस कक्षाएं" होती हैं, यानी आधार वर्ग जहां सभी विधियां शुद्ध वर्चुअल होती हैं, कोई भी कार्यान्वयन नहीं करता है [याद रखें कि आप अभी भी कार्यान्वयन को परिभाषित कर सकते हैं, लेकिन आपको इसे आमंत्रित करना होगा स्पष्ट रूप से], और कोई डेटा सदस्य नहीं हैं। जावा में "इंटरफेस" के समान या (जो मैंने सुना है) सी #।

सी ++ में बहुरूपता का उपयोग करने के लिए, आप संरचना का उपयोग नहीं कर सकते हैं, आपको (सार्वजनिक) विरासत का उपयोग करना होगा।

तो यदि कक्षा बार प्रिंट करने योग्य और सीरियलज़ेबल से प्राप्त (सार्वजनिक रूप से) प्राप्त करता है, तो मैं ऑब्जेक्ट को प्रिंट करने योग्य ऑब्जेक्ट, एक धारावाहिक वस्तु, या बार ऑब्जेक्ट (पॉइंटर्स या संदर्भों का उपयोग करके) का इलाज कर सकता हूं।

संरचना के साथ, आप ऐसा नहीं कर सकते हैं।

0

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

एक इनहेरिट बी, बी, बी

जब जरूरत विरासत के इस प्रकार का उपयोग करने के उठता है।

उनकी कर्नेल लाइब्रेरी ओपन सोर्स है और यदि आप उदाहरण देखना चाहते हैं तो एकाधिक विरासत का उपयोग बड़े पैमाने पर किया जाता है।

http://sourceforge.net/projects/eiffelstudio/files/

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