एकाधिक वंशानुक्रम मामलों का उपयोग करते हैं


15

जावा इस आधार पर कई विरासतों को छोड़ देता है कि यह भाषा को सरल रखने के डिजाइन लक्ष्य का पालन करता है

मुझे आश्चर्य है कि अगर जावा (इसके इको-सिस्टम के साथ) वास्तव में "सरल" है। पायथन जटिल नहीं है और इसमें कई विरासत हैं। तो बहुत व्यक्तिपरक होने के बिना, मेरा सवाल है ...

विशिष्ट समस्या पैटर्न क्या हैं जो एक कोड से लाभान्वित होते हैं जो कई विरासतों का भारी उपयोग करने के लिए डिज़ाइन किया गया है


8
जावा बहुत कम कारण के लिए पूरी तरह से अच्छी चीजों का एक भयानक भाग छोड़ देता है। मैं एमआई के लिए एक उचित औचित्य की उम्मीद नहीं करूंगा।
डेडएमजी

2
पाइथन की बहु विरासत में निश्चित रूप से यहाँ-ड्रेगन क्षेत्र है। यह तथ्य कि यह गहराई-पहले, बाएं से दाएं नाम के संकल्प का उपयोग करता है , दोनों में स्थिरता और समझ के लिए महत्वपूर्ण मुद्दे हैं। हालांकि यह उथले वर्ग के पदानुक्रमों में उपयोगी हो सकता है, यह गहरे लोगों में एक अविश्वसनीय रूप से प्रति-सहज ज्ञान युक्त हो सकता है।
मार्क बूथ

मुझे लगता है कि जावा में एक से अधिक वंशानुक्रम नहीं होने का कारण यह है कि जावा डेवलपर्स चाहते थे कि उनकी भाषा सीखना आसान हो। एकाधिक विरासत, जबकि कुछ मामलों में अविश्वसनीय रूप से शक्तिशाली है, समझ के लिए कठिन है, और यहां तक ​​कि अच्छे प्रभाव के लिए इस्तेमाल किया जाना कठिन है; यह वह चीज नहीं है जिसके साथ आप एक प्रोग्रामिंग फ्रेशमैन से भिड़ना चाहेंगे। मेरा मतलब है: आप किसी को आभासी विरासत की व्याख्या कैसे करते हैं जो विरासत की अवधारणा के साथ संघर्ष कर रहा है? और, चूंकि कई उत्तराधिकार भी कार्यान्वयनकर्ताओं की तरफ बिल्कुल तुच्छ नहीं हैं, इसलिए जावा देव की संभावना है कि इसे छोड़ देना एक जीत है।
विस्फ़ोटक -

जावा नाममात्र टाइप किया गया है। अजगर नहीं है। यह कई विरासत को पायथन में लागू करने और समझने दोनों को बहुत आसान बनाता है।
जूल्स

जवाबों:


11

पेशेवरों:

  1. यह कभी-कभी एक समस्या के स्पष्ट मॉडलिंग की अनुमति देता है अन्य तरीकों से इसे मॉडल करने की।
  2. यदि अलग-अलग पेरेन्ट्स का ऑर्थोगोनल उद्देश्य है, तो यह किसी प्रकार की रचना की अनुमति दे सकता है

विपक्ष:

  1. अगर अलग-अलग माता-पिता के पास ऑर्थोगोनल उद्देश्य नहीं है, तो यह समझने में मुश्किल है।
  2. यह समझना आसान नहीं है कि इसे किसी भाषा (किसी भी भाषा) में कैसे लागू किया जाता है।

C ++ में ऑर्थोगोनल फीचर्स के लिए उपयोग की जाने वाली मल्टीपल इनहेरिटेंस का एक अच्छा उदाहरण है जब आप CRTP का उपयोग करते हैं, उदाहरण के लिए, किसी गेम के लिए कंपोनेंट सिस्टम सेटअप करें।

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

आप इस लायब्रेरी के अन्य उदाहरणों को देख सकते हैं , जैसे कि मेमोरी आवंटन को एक महीन अनाज के तरीके से प्रबंधित किया जाता है, जिससे कि CRTP वर्ग के वेरिएंट से नई और अतिभारित होने वाली श्रेणी से वारिस बनाया जाता है

जैसा कि कहा गया है, कई विरासत के साथ मुख्य समस्याएं संबंधित अवधारणाओं को मिलाने से पैदा होती हैं। इससे भाषा को जटिल कार्यान्वयन सेट करना पड़ता है (जिस तरह से C ++ हीरे की समस्या के साथ खेलने की अनुमति देता है ...) और उपयोगकर्ता यह सुनिश्चित नहीं कर रहा है कि उस कार्यान्वयन में क्या हो रहा है। उदाहरण के लिए, इस लेख को यह बताते हुए पढ़ें कि यह C ++ में कैसे लागू किया जाता है

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


मैं वास्तव में सराहना करूंगा यदि आप एक उदाहरण की समस्या के साथ अपना जवाब दे - कि "orthogonal उद्देश्य" की तरह स्पष्ट हो जाएगा - लेकिन धन्यवाद
treecoder

ठीक है मुझे कुछ जोड़ने की कोशिश करो।
Kलेम

Ogre3D कोई ऐसी जगह नहीं है जहां मैं डिजाइन प्रेरणा के लिए देखूं- क्या आपने उनके सिंग्लटन संक्रमण को देखा है?
डेडएमजी

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

4

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


+1 यह वास्तव में एकाधिक उत्तराधिकार के लिए एक अच्छा कारण है। मिक्सिन्स अतिरिक्त अर्थों को ले जाते हैं ("इस वर्ग को एक स्टैंड-अलोन के रूप में इस्तेमाल नहीं किया जाना चाहिए")
ashes999

2

मुझे लगता है कि विकल्प मुख्य रूप से हीरे की समस्या के कारण मुद्दों पर आधारित है

इसके अलावा, अक्सर प्रतिनिधि या अन्य माध्यमों से कई विरासत के उपयोग को दरकिनार करना संभव है।

मुझे आपके अंतिम प्रश्न के अर्थ पर यकीन नहीं है। लेकिन अगर यह "किन मामलों में एकाधिक उत्तराधिकार उपयोगी है?", तो उन सभी मामलों में जहां आप एक वस्तु ए, बी और सी की कार्यात्मकता वाले ए, मूल रूप से करना चाहेंगे।


2

मैं यहाँ बहुत कुछ नहीं करूँगा, लेकिन आप निश्चित रूप से निम्नलिखित लिंक http://docs.python.org/release/1.5.1p1/tut/multiple.html के माध्यम से अजगर में कई विरासत को समझ सकते हैं :

केवल शब्दार्थ को समझाने के लिए आवश्यक नियम वर्ग विशेषता संदर्भों के लिए उपयोग किया जाने वाला संकल्प नियम है। यह गहराई-पहले, बाएं से दाएं है। इस प्रकार, यदि कोई विशेषता DerivedClassName में नहीं पाई जाती है, तो इसे Base1 में खोजा जाता है, तो Base1 के आधार वर्गों में (पुनरावर्ती), और केवल यदि यह वहां नहीं पाया जाता है, तो यह Base2 में खोजा जाता है, और इसी तरह।

...

यह स्पष्ट है कि कई वंशानुक्रम का अंधाधुंध उपयोग एक रखरखाव दुःस्वप्न है, जिसे आकस्मिक नाम संघर्ष से बचने के लिए सम्मेलनों पर पायथन में निर्भरता दी गई है। एकाधिक वंशानुक्रम के साथ एक अच्छी तरह से ज्ञात समस्या दो वर्गों से उत्पन्न एक वर्ग है जो एक सामान्य आधार वर्ग होता है। हालांकि यह पता लगाना काफी आसान है कि इस मामले में क्या होता है (उदाहरण में '`उदाहरण चर' या सामान्य आधार वर्ग द्वारा उपयोग की जाने वाली डेटा विशेषताओं की एक एकल प्रति होगी), यह स्पष्ट नहीं है कि ये शब्दार्थ किसी भी तरह से हैं उपयोगी।

यह सिर्फ एक छोटा पैराग्राफ है लेकिन मेरे द्वारा अनुमान लगाए गए संदेह को दूर करने के लिए काफी बड़ा है।


1

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


1
क्या इसके लिए एक से अधिक वंशानुक्रम की आवश्यकता होती है, या केवल एक साधन जिसके द्वारा कोई इंटरफ़ेस अनपेक्षित विधियों के लिए डिफ़ॉल्ट व्यवहार निर्दिष्ट कर सकता है? यदि इंटरफेस केवल उन तरीकों के लिए डिफ़ॉल्ट कार्यान्वयन को निर्दिष्ट कर सकते हैं जो वे स्वयं कार्यान्वित करते हैं (जैसा कि वे उन अन्य इंटरफेस से विरासत में मिला है) तो ऐसी सुविधा दोहरे-हीरे के मुद्दों से पूरी तरह से बच जाएगी जो कई विरासत को मुश्किल बनाते हैं।
सुपरकैट

1

विशिष्ट समस्या पैटर्न क्या हैं जो कई विरासतों के भारी उपयोग करने के लिए डिज़ाइन किए गए कोड से लाभ उठाते हैं?

यह सिर्फ एक उदाहरण है, लेकिन एक मैं फोन करने वालों या उपवर्गों में कैस्केडिंग परिवर्तन लागू करने के लिए सुरक्षा में सुधार करने और प्रलोभन को कम करने के लिए अमूल्य पाता हूं।

जहां मुझे कई विरासत मिली हैं, जो सबसे अमूर्त के लिए भी अविश्वसनीय रूप से उपयोगी है, सी + + में नॉन-वर्चुअल इंटरफ़ेस मुहावरा (एनवीआई) है।

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

सरल उदाहरण (कुछ की जाँच हो सकती है कि पास किया गया फ़ाइल हैंडल खुला है या ऐसा कुछ है):

// Non-virtual interface (public methods are nonvirtual/final).
// Since these are modeling the concept of "interface", not ABC,
// multiple will often be inherited ("implemented") by a subclass.
class SomeInterface
{
public:
    // Pre: x should always be greater than or equal to zero.
    void f(int x) /*final*/
    {
        // Make sure x is actually greater than or equal to zero
        // to meet the necessary pre-conditions of this function.
        assert(x >= 0);

        // Call the overridden function in the subtype.
        f_impl(x);
    }

protected:
    // Overridden by a boatload of subtypes which implement
    // this non-virtual interface.
    virtual void f_impl(int x) = 0;
};

इस मामले में, शायद fएक हजार स्थानों द्वारा कोडबेस में बुलाया जाता है, जबकि f_implसौ उपवर्गों द्वारा ओवरराइड किया जाता है।

उन सभी 1000 स्थानों पर इस तरह की सुरक्षा जांच करना मुश्किल होगा जो कॉल fया ओवरराइड करने वाले सभी 100 स्थानों पर करते हैं f_impl

केवल इस प्रविष्टि को कार्यक्षमता के लिए गैर-संवैधानिक बनाकर, यह मुझे इस जाँच को करने के लिए एक केंद्रीय स्थान देता है। और यह जांच थोड़ी सी भी कमी को कम नहीं कर रही है, क्योंकि यह केवल इस फ़ंक्शन को कॉल करने के लिए आवश्यक एक पूर्व शर्त है। एक अर्थ में, यह यकीनन इंटरफ़ेस द्वारा प्रदान किए गए अनुबंध को मजबूत कर रहा है, और xयह सुनिश्चित करने के लिए इनपुट की जांच के बोझ से राहत देता है कि यह सभी 100 स्थानों पर वैध पूर्व शर्त के अनुरूप है जो इसे ओवरराइड करते हैं।

यह कुछ ऐसा है जो मैं चाहता हूं कि हर भाषा हो, और सी ++ में भी कामना हो, कि यह एक देशी अवधारणा से थोड़ा अधिक था (उदाहरण: हमें ओवरराइड करने के लिए एक अलग फ़ंक्शन को परिभाषित करने की आवश्यकता नहीं है)।

यह बेहद उपयोगी है यदि आपने पहले से ऐसा नहीं किया है assert, और आपको एहसास हुआ कि आपको बाद में इसकी आवश्यकता है जब कोडबेस के कुछ यादृच्छिक स्थानों पर नकारात्मक मानों का सामना किया जा रहा था f


0

पहला: आधार वर्ग और (व्युत्पन्न वर्ग) के आधार और तंग युग्मन के आधार वर्ग की कई प्रतियाँ।

दूसरा: अमूर्त इंटरफेस से कई विरासत


क्या आप यह सुझाव दे रहे हैं कि यह किसी भी संदर्भ में उपयोगी नहीं है? और इसके बिना सब कुछ आसानी से डिज़ाइन / कोड किया जा सकता है? कृपया दूसरे बिंदु पर भी विस्तार से बताएं।
ट्रेकोडर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.