जावा या C # में मल्टीपल इनहेरिटेंस की अनुमति क्यों नहीं है?


115

मुझे पता है कि जावा और C # में कई उत्तराधिकार की अनुमति नहीं है। कई किताबें बस कहती हैं, कई विरासत की अनुमति नहीं है। लेकिन इंटरफेस का उपयोग करके इसे लागू किया जा सकता है। इसकी अनुमति क्यों नहीं है, इस बारे में कुछ भी चर्चा नहीं की गई है। क्या कोई मुझे ठीक से बता सकता है कि इसकी अनुमति क्यों नहीं है?


1
केवल यह इंगित करने के लिए कि वहाँ रूपरेखाएँ हैं जो C # कक्षाओं में MI जैसे व्यवहार की अनुमति देती हैं। और निश्चित रूप से आपके पास स्टेटलेस मिश्रणों (एक्सटेंशन विधियों का उपयोग करके) होने का विकल्प है - स्टेटलेस होने के बावजूद वे बहुत उपयोगी नहीं हैं।
दिमित्री नेस्टरुक

1
इंटरफेस के साथ कुछ भी करना है विरासत में भाषा वाक्य रचना द्वारा बनाया गया एक भ्रम है। विरासत आपको अमीर बनाने वाली है। एक इंटरफेस के लिए ऐसा कुछ नहीं है, आपको स्क्वाट विरासत में नहीं मिलता है और यह आपको काफी गरीब बनाता है। आपको चाचा हैरी का जुआ ऋण विरासत में मिला, इंटरफ़ेस को लागू करने के लिए आपके पास और अधिक काम है।
हंस पसंत

जवाबों:


143

संक्षिप्त उत्तर है: क्योंकि भाषा डिजाइनरों ने फैसला नहीं किया है।

मूल रूप से, ऐसा लगता था कि .NET और जावा दोनों डिज़ाइनरों ने कई उत्तराधिकार की अनुमति नहीं दी थी क्योंकि उन्होंने तर्क दिया था कि एमआई को जोड़ने से भाषाओं को बहुत अधिक जटिलता मिलती है जबकि बहुत कम लाभ प्रदान करते हैं

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

  1. एमआई कैसे काम करता है, इसके लिए विभिन्न भाषाओं में वास्तव में अलग-अलग अपेक्षाएं हैं। उदाहरण के लिए, संघर्षों का समाधान कैसे किया जाता है और क्या डुप्लिकेट आधारों को विलय या निरर्थक किया जाता है। सीएलआर में एमआई को लागू करने से पहले, हमें सभी भाषाओं का एक सर्वेक्षण करना होगा, सामान्य अवधारणाओं का पता लगाना होगा, और यह तय करना होगा कि उन्हें भाषा-तटस्थ तरीके से कैसे व्यक्त किया जाए। हमें यह भी तय करना होगा कि क्या एमआई सीएलएस में है और इसका मतलब उन भाषाओं के लिए होगा जो इस अवधारणा को नहीं चाहते हैं (उदाहरण के लिए, VB.NET। बेशक, यह वह व्यवसाय है जो हम एक सामान्य भाषा रनटाइम के रूप में कर रहे हैं, लेकिन हम इसे अभी तक एमआई के लिए करने के आसपास नहीं हैं।

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

  3. मल्टीपल इम्प्लीमेंटेशन इनहेरिटेंस इंप्लीमेंटेशन में बहुत अधिक जटिलता को इंजेक्ट करता है। यह जटिलता कास्टिंग, लेआउट, प्रेषण, फ़ील्ड एक्सेस, क्रमांकन, पहचान तुलना, सत्यापन, प्रतिबिंब, जेनरिक और संभवतः अन्य स्थानों को प्रभावित करती है।

आप यहां पर पूरा लेख पढ़ सकते हैं।

जावा के लिए, आप इस लेख को पढ़ सकते हैं :

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

डिजाइनरों की राय में, एक से अधिक विरासत से समस्याएँ और भ्रम पैदा होते हैं। इसलिए वे भाषा से कई वंशानुक्रम में कटौती करते हैं (जिस तरह वे ऑपरेटर ओवरलोडिंग को काटते हैं)। डिजाइनरों के व्यापक सी ++ अनुभव ने उन्हें सिखाया कि कई उत्तराधिकार सिर्फ सिरदर्द के लायक नहीं थे।


10
अच्छी तुलना। विचार-प्रक्रियाओं का पर्याप्त संकेत जो मेरे विचार से दोनों प्लेटफार्मों को रेखांकित करता है।
कर्टनडॉग

97

कार्यान्वयन की कई विरासत जो अनुमति नहीं है।

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

मेरा मानना ​​है कि इसे डबल डायमंड इनहेरिटेंस समस्या कहा जाता है।


80
आपको सड़क पर मृत किसी व्यक्ति का प्यारा पानी का झरना मिल जाता है :-)
Dan F

क्या यह एकमात्र समस्या है? मुझे लगता है, मुझे यकीन नहीं है, कि सी ++ वर्चुअल कीवर्ड द्वारा इस समस्या को हल करता है, क्या यह सच है? मैं C ++ में अच्छा नहीं हूँ
अब्दुलात्सर मोहम्मद

2
C ++ में आप या तो यह बता सकते हैं कि बेस क्लास के कौन से फंक्शन्स में कॉल की गई है या इसे खुद ही फिर से लागू किया जा सकता है।
दिमित्री रिसेनबर्ग

1
आधुनिक डिजाइन सभी में सरलतम मामलों में विरासत पर रचना का पक्ष लेते हैं। एकाधिक वंशानुक्रम को एक साधारण मामले के रूप में कभी नहीं गिना जाता। रचना के साथ, आपके पास इस बात पर सटीक नियंत्रण होता है कि आपकी कक्षा क्या करती है जब हीरे की समस्याएँ होती हैं जैसे ...
Bill Michell

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

19

कारण: जावा अपनी सादगी के कारण बहुत लोकप्रिय और कोड के लिए आसान है।

तो क्या कभी जावा डेवलपर्स प्रोग्रामर के लिए समझने में मुश्किल और जटिल महसूस करते हैं, उन्होंने इससे बचने की कोशिश की। इस तरह की एक संपत्ति कई विरासत है।

  1. उन्होंने संकेत देने वालों से परहेज किया
  2. वे कई विरासत से बचते थे।

एकाधिक विरासत के साथ समस्या: हीरा समस्या।

उदाहरण :

  1. मान लें कि कक्षा ए में एक विधि मजेदार है ()। वर्ग A से वर्ग B और वर्ग C प्राप्त होता है।
  2. और दोनों वर्गों बी और सी, विधि मज़ा () से अधिक है।
  3. अब मान लें कि कक्षा D को वर्ग B, और C. दोनों की विरासत मिलती है (बस मान लें)
  4. कक्षा डी के लिए ऑब्जेक्ट बनाएं।
  5. डी डी = नया डी ();
  6. और d.fun () तक पहुँचने का प्रयास करें; => इसे क्लास बी का मज़ा () या क्लास सी का मज़ा () कहेंगे?

यह हीरे की समस्या में विद्यमान अस्पष्टता है।

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

नोट : लेकिन किसी भी तरह से आप हमेशा इंटरफेस का उपयोग करके अप्रत्यक्ष रूप से कई विरासत को लागू कर सकते हैं।


1
"लेकिन किसी भी तरह से आप हमेशा इंटरफेस का उपयोग करके कई विरासत को अप्रत्यक्ष रूप से लागू कर सकते हैं।" - जिसे प्रोग्रामर को हर बार, बार-बार तरीकों की बॉडी को फिर से निर्दिष्ट करने की आवश्यकता होती है।
कारी

13

क्योंकि जावा में C ++ से बहुत अलग डिज़ाइन दर्शन है। (मैं यहां C # पर चर्चा नहीं करने जा रहा हूं।)

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

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

इसके अलावा, जावा काफी हद तक C ++ और स्मॉलटाक, सबसे अच्छी ज्ञात OO भाषाओं की प्रतिक्रिया थी। अन्य OO भाषाओं के बहुत सारे हैं (आम लिस्प वास्तव में मानकीकृत होने वाला पहला था), विभिन्न OO सिस्टम के साथ जो एमआई को बेहतर तरीके से संभालते हैं।

यह उल्लेख करने के लिए नहीं कि इंटरफेस, रचना और प्रतिनिधिमंडल का उपयोग करके जावा में एमआई करना पूरी तरह से संभव है। यह C ++ की तुलना में अधिक स्पष्ट है, और इसलिए इसका उपयोग करने के लिए अनाड़ी है लेकिन आपको पहली नज़र में समझने की अधिक संभावना है।

यहाँ कोई सही उत्तर नहीं है। अलग-अलग उत्तर हैं, और जो किसी दिए गए स्थिति के लिए बेहतर है, वह अनुप्रयोगों और व्यक्तिगत वरीयता पर निर्भर करता है।


12

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


8

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


8

मल्टीपल इनहेरिटेंस है

  • समझने केलिए कठिन
  • डीबग करना कठिन है (उदाहरण के लिए, यदि आप कई चौखटे से कक्षाएं मिलाते हैं, जिसमें पहचान के तौर पर नामित तरीके गहरे हैं, तो बहुत अप्रत्याशित तालमेल हो सकता है)
  • गलत उपयोग करने में आसान
  • वास्तव में ऐसा नहीं है उपयोगी
  • लागू करने के लिए कठिन, खासकर यदि आप चाहते हैं कि यह सही ढंग से और कुशलता से किया जाए

इसलिए, यह जावा भाषा में एकाधिक वंशानुक्रम को शामिल नहीं करने के लिए एक बुद्धिमान विकल्प माना जा सकता है ।


3
मैं उपरोक्त सभी से असहमत हूं, कॉमन लिस्प ऑब्जेक्ट सिस्टम के साथ काम किया है।
डेविड थॉर्नले

2
डायनेमिक भाषाएं गिनती नहीं करती हैं ;-) किसी भी लिस्प जैसी प्रणाली में, आपके पास एक REPL होता है जो डिबगिंग को आसान बनाता है। इसके अलावा, सीएलओएस (जैसा कि मैं इसे समझता हूं, मैंने वास्तव में इसका इस्तेमाल कभी नहीं किया है, केवल इसके बारे में पढ़ा है) एक मेटा-ऑब्जेक्ट-सिस्टम है, जिसमें बहुत लचीलापन और एक रोल-अपना-अपना दृष्टिकोण है। लेकिन C ++ की तरह एक संकलित भाषा पर विचार करें, जहां कंपाइलर कई (संभवतः ओवरलैपिंग) vtables का उपयोग करके कुछ ज्वलनशील जटिल विधि लुकअप उत्पन्न करता है: इस तरह के कार्यान्वयन में, यह पता लगाना कि किस विधि का कार्यान्वयन किया गया था, एक नहीं तो-तुच्छ कार्य हो सकता है।
एमएफएक्स

5

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


4

पुराने दिनों में वापस ('70 के दशक) जब कंप्यूटर साइंस अधिक विज्ञान था और कम बड़े पैमाने पर उत्पादन प्रोग्रामर के पास अच्छे डिजाइन और अच्छे कार्यान्वयन के बारे में सोचने का समय था और परिणामस्वरूप उत्पादों (प्रोग्राम) की उच्च गुणवत्ता (जैसे टीसीपी / आईपी डिजाइन) थी। और कार्यान्वयन)। आजकल, जब हर कोई प्रोग्रामिंग कर रहा है, और प्रबंधक समय सीमा से पहले चश्मा बदल रहे हैं, स्टीव हाघ पोस्ट से विकिपीडिया लिंक में वर्णित एक जैसे सूक्ष्म मुद्दों को ट्रैक करना मुश्किल है; इसलिए, "मल्टीपल इनहेरिटेंस" कंपाइलर डिज़ाइन द्वारा सीमित है। यदि आप इसे पसंद करते हैं, तो आप अभी भी C ++ का उपयोग कर सकते हैं .... और आपके पास सभी स्वतंत्रताएं हैं :)


4
... पैर में खुद को गोली मारने की स्वतंत्रता सहित, कई बार;)
मारियो ऑर्टगॉन

4

मैं एक चुटकी नमक के साथ "जावा में एकाधिक वंशानुक्रम की अनुमति नहीं है" बयान लेता हूं।

मल्टीपल इनहेरिटेंस को तब परिभाषित किया जाता है जब एक "प्रकार" एक से अधिक "प्रकार" से विरासत में मिलता है। और इंटरफेस को भी उन प्रकारों के रूप में वर्गीकृत किया जाता है जैसे उनके पास व्यवहार होता है। तो जावा में कई विरासत हैं। बस यह सुरक्षित है।


6
लेकिन आपको एक इंटरफ़ेस से विरासत नहीं मिली है, आप इसे लागू करते हैं। इंटरफेस कक्षाएं नहीं हैं।
Blorgbeard 11:15 पर

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

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

4

कक्षाओं का गतिशील लोडिंग कई वंशानुक्रम के कार्यान्वयन को कठिन बनाता है।

जावा में वास्तव में वे एकल वंशानुक्रम और इंटरफ़ेस का उपयोग करके कई उत्तराधिकार की जटिलता से बचते थे। नीचे दी गई स्थिति की तरह कई विरासत की जटिलता बहुत अधिक है

बहु विरासत की हीरे की समस्या। हमारे पास ए और विरासत से दो वर्ग बी और सी हैं। मान लें कि बी और सी विरासत में मिली विधि से आगे निकल रहे हैं और वे अपना स्वयं का कार्यान्वयन प्रदान करते हैं। अब D, B और C दोनों से विरासत में मिला है। D को उस ओवरराइड विधि को विरासत में प्राप्त करना चाहिए, jvm यह तय करने में सक्षम नहीं हो सकता कि किस ओवरराइड विधि का उपयोग किया जाएगा?

C ++ में वर्चुअल फ़ंक्शंस को हैंडल करने के लिए उपयोग किया जाता है और हमें स्पष्ट रूप से करना होगा।

इंटरफेस का उपयोग करके इससे बचा जा सकता है, कोई विधि निकाय नहीं हैं। इंटरफेस को तत्काल नहीं किया जा सकता है - वे केवल कक्षाओं द्वारा लागू किया जा सकता है या अन्य इंटरफेस द्वारा बढ़ाया जा सकता है।


3

अगर विरासत में मिले वर्गों का समान कार्य है तो वास्तव में कई विरासत एक जटिलता पैदा करेंगे। अर्थात कंपाइलर को एक भ्रम होगा जिसे किसी को (हीरे की समस्या) को चुनना होगा। तो जावा में उस जटिलता को हटा दिया गया और इंटरफ़ेस को प्राप्त करने के लिए कार्यक्षमता दी गई जैसे कई विरासत दी गई। हम इंटरफ़ेस का उपयोग कर सकते हैं


2

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

या, सुपरक्लास कंस्ट्रक्टर द्वारा कॉल करते समय super(), किस सुपर क्लास कंस्ट्रक्टर को बुलाया जाएगा?

वर्तमान जावा एपीआई सुविधाओं से यह निर्णय असंभव है। जावा में इतने सारे वंशानुक्रम की अनुमति नहीं है।


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

1

जावा में सीधे कई इनहेरिटेंस की अनुमति नहीं है, लेकिन इंटरफेस के माध्यम से इसकी अनुमति है।

कारण :

मल्टीपल इनहेरिटेंस: अधिक जटिलता और अस्पष्टता का परिचय देता है।

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

अधिक सटीक रूप से, वे अतिरिक्त विशेषता वाले जावा में एक विशेष निर्माण हैं जो आपको एक प्रकार के कई वंशानुक्रम अर्थात कक्षाएं करने की अनुमति देते हैं जिन्हें एक से अधिक वर्ग तक किया जा सकता है।

सरल उदाहरण लेते हैं।

  1. मान लीजिए कि एक ही विधि के नाम लेकिन अलग-अलग प्रकार्य के साथ 2 सुपरक्लास वर्ग ए और बी हैं। निम्नलिखित कोड के साथ (फैली हुई) कीवर्ड के साथ कई विरासत संभव नहीं है।

       public class A                               
         {
           void display()
             {
               System.out.println("Hello 'A' ");
             }
         }
    
       public class B                               
          {
            void display()
              {
                System.out.println("Hello 'B' ");
              }
          }
    
      public class C extends A, B    // which is not possible in java
        {
          public static void main(String args[])
            {
              C object = new C();
              object.display();  // Here there is confusion,which display() to call, method from A class or B class
            }
        }
  2. लेकिन इंटरफेस के माध्यम से, (औजार) कीवर्ड के साथ कई विरासत संभव है।

    interface A
        {
           // display()
        }
    
    
     interface B
        {
          //display()
        }
    
     class C implements A,B
        {
           //main()
           C object = new C();
           (A)object.display();     // call A's display
    
           (B)object.display(); //call B's display
        }
    }

0

क्या कोई मुझे ठीक से बता सकता है कि इसकी अनुमति क्यों नहीं है?

आप इस दस्तावेज़ के लिंक से उत्तर पा सकते हैं

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

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

  1. क्या होगा अगर विभिन्न सुपर क्लास के तरीके या कंस्ट्रक्टर एक ही क्षेत्र को तुरंत प्रभावित करते हैं?

  2. कौन सी विधि या निर्माणकर्ता पूर्वता लेगा?

भले ही राज्य की कई विरासत अब अनुमति दी गई है, फिर भी आप इसे लागू कर सकते हैं

एक से अधिक वंशानुक्रम : एक से अधिक इंटरफ़ेस को लागू करने के लिए एक वर्ग की क्षमता।

कार्यान्वयन की एकाधिक विरासत (इंटरफेस में डिफ़ॉल्ट तरीकों के माध्यम से): कई वर्गों से विरासत में मिली परिभाषाओं की क्षमता

अतिरिक्त जानकारी के लिए इस संबंधित SE प्रश्न का संदर्भ लें:

इंटरफ़ेस के साथ कई वंशानुक्रम की अस्पष्टता


0

C ++ में एक वर्ग एक से अधिक वर्गों से उत्तराधिकार (प्रत्यक्ष या अप्रत्यक्ष रूप से) ले सकता है, जिसे एकाधिक उत्तराधिकार के रूप में संदर्भित किया जाता है

हालाँकि, C # और Java, कक्षाओं को एकल वंशानुक्रम तक सीमित करते हैं, प्रत्येक वर्ग को एकल पैरेंट क्लास से विरासत में मिला है।

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

यदि दो फ्रेमवर्क अपवादों के लिए अपने स्वयं के आधार वर्गों को परिभाषित करते हैं, उदाहरण के लिए, आप अपवाद वर्गों को बनाने के लिए कई विरासत का उपयोग कर सकते हैं जो या तो फ्रेमवर्क के साथ उपयोग किए जा सकते हैं।

मल्टीपल इनहेरिटेंस के साथ समस्या यह है कि इससे अस्पष्टता हो सकती है। क्लासिक उदाहरण है जब एक वर्ग दो अन्य वर्गों से विरासत में मिला है, जिनमें से प्रत्येक एक ही वर्ग से विरासत में मिला है:

class A {
    protected:
    bool flag;
};
class B : public A {};
class C : public A {};
class D : public B, public C {
    public:
    void setFlag( bool nflag ){
        flag = nflag; // ambiguous
    }
};

इस उदाहरण में, flagडेटा सदस्य द्वारा परिभाषित किया गया है class A। लेकिन class Dसे उतरता है class B और class C, जो दोनों प्राप्त से A, संक्षेप में इतना दो प्रतियां की flagवजह से दो उदाहरणों से उपलब्ध हैं Aमें हैं Dके वर्ग पदानुक्रम। आप कौन सा सेट करना चाहते हैं? संकलक शिकायत है कि के संदर्भ flagमें Dहै अस्पष्ट । एक फिक्स संदर्भ को स्पष्ट रूप से खारिज करना है:

B::flag = nflag;

एक और फिक्स है बी और सी को घोषित करना virtual base classes , जिसका अर्थ है कि ए की केवल एक प्रति पदानुक्रम में मौजूद हो सकती है, किसी भी अस्पष्टता को समाप्त कर सकती है।

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

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


-1

इस उदाहरण की कल्पना करें: मेरे पास एक वर्ग है Shape1

यह CalcualteAreaविधि है:

Class Shape1
{

 public void CalculateArea()

     {
       //
     }
}

एक और वर्ग है Shape2कि एक ही विधि भी है

Class Shape2
{

 public void CalculateArea()

     {

     }
}

अब मेरे पास एक चाइल्ड क्लास सर्कल है, यह शेप 1 और शेप 2 दोनों से प्राप्त होता है;

public class Circle: Shape1, Shape2
{
}

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

लेकिन कई इंटरफेस हो सकते हैं क्योंकि इंटरफेस में विधि की परिभाषा नहीं होती है। यहां तक ​​कि दोनों इंटरफेस में एक ही विधि है, दोनों का कोई कार्यान्वयन नहीं है और हमेशा बच्चे वर्ग में विधि को निष्पादित किया जाएगा।


भाषा डिजाइनर स्पष्ट तरीके से कॉल दे सकता है जैसे वे इंटरफ़ेस में करते हैं। ऐसी कोई बात नहीं है! एक और कारण है कि अमूर्त तरीकों के साथ अमूर्त वर्ग के बारे में अब आप कैसे विचार करते हैं?
नाओमी अली
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.