एकाधिक वंशानुक्रम: Difference between revisions
No edit summary |
No edit summary |
||
Line 1: | Line 1: | ||
एकाधिक वंशानुक्रम कुछ [[ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग]] [[प्रोग्रामिंग भाषा|भाषा]] की ऐसी विशेषता है जिसमें ऑब्जेक्ट या क्लास (कंप्यूटर प्रोग्रामिंग) एकल से अधिक पैरेंट ऑब्जेक्ट या सुपरक्लास (कंप्यूटर साइंस) से [[वंशानुक्रम (वस्तु-उन्मुख प्रोग्रामिंग)]] कर सकता है। यह एकल वंशानुक्रम से भिन्न है, जहाँ एकल वस्तु या वर्ग केवल एकल विशेष वस्तु या वर्ग से प्राप्त हो सकता है। | एकाधिक वंशानुक्रम कुछ [[ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग]] [[प्रोग्रामिंग भाषा|भाषा]] की ऐसी विशेषता है जिसमें ऑब्जेक्ट या क्लास (कंप्यूटर प्रोग्रामिंग) एकल से अधिक पैरेंट ऑब्जेक्ट या सुपरक्लास (कंप्यूटर साइंस) से [[वंशानुक्रम (वस्तु-उन्मुख प्रोग्रामिंग)]] कर सकता है। यह एकल वंशानुक्रम से भिन्न है, जहाँ एकल वस्तु या वर्ग केवल एकल विशेष वस्तु या वर्ग से प्राप्त हो सकता है। | ||
एकाधिक वंशानुक्रम कई वर्षों से | एकाधिक वंशानुक्रम कई वर्षों से संदेहयुक्त विषय रहा है,<ref>{{cite journal |last=Cargill |first=T. A. |date=Winter 1991 |title=Controversy: The Case Against Multiple Inheritance in C++ |journal=Computing Systems |volume=4 |number=1 |pages=69–82}}</ref><ref>{{cite journal |last=Waldo |first=Jim |date=Spring 1991 |title=Controversy: The Case For Multiple Inheritance in C++ |journal=Computing Systems |volume=4 |number=2 |pages=157–171}}</ref> विरोधियों के साथ हीरे की समस्या जैसी स्थितियों में इसकी बढ़ी हुई जटिलता और अस्पष्टता की ओर संकेत करते हुए, जहां यह अस्पष्ट हो सकता है कि किस मूल वर्ग से विशेष विशेषता उत्तराधिकार में मिली है यदि एकल से अधिक मूल वर्ग उक्त विशेषता को प्रारम्भ करते हैं। वर्चुअल उत्तराधिकार का उपयोग करने सहित इसे विभिन्न उपाये से संबोधित किया जा सकता है।<ref>{{cite web |last1=Schärli |first1=Nathanael |last2=Ducasse |first2=Stéphane |last3=Nierstrasz |first3=Oscar |last4=Black |first4=Andrew |title=Traits: Composable Units of Behavior |website=Web.cecs.pdx.edu |url=http://web.cecs.pdx.edu/~black/publications/TR_CSE_02-012.pdf |format=PDF |access-date=2016-10-21}}</ref> अस्पष्टता को संबोधित करने के लिए ऑब्जेक्ट संरचना के वैकल्पिक उपाये जैसे मिश्रण और [[विशेषता (कंप्यूटर प्रोग्रामिंग)]] पर आधारित नहीं है। | ||
== विवरण == | == विवरण == | ||
ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग (OOP) में, वंशानुक्रम दो वर्गों के | ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग (OOP) में, वंशानुक्रम दो वर्गों के मध्य एकल संबंध का वर्णन करता है जिसमें (चाइल्ड क्लास) वर्ग, पैरेंट क्लास को उप-वर्गित करता है। बच्चा माता-पिता की विधियों और विशेषताओं को उत्तराधिकार में प्राप्त करता है, जिससे भागीदारी में कार्यक्षमता की अनुमति मिलती है। उदाहरण के लिए, कोई चर वर्ग स्तनपायी बना सकता है जिसमें खाने, प्रजनन, आदि जैसी विशेषताएं हों फिर एकल चाइल्ड क्लास कैट को परिभाषित करें जो चूहों का पीछा करने जैसी नई सुविधाओं को जोड़ते हुए उन विशेषताओं को स्पष्ट रूप से प्रोग्राम किए बिना प्रदान करती है। | ||
एकाधिक वंशानुक्रम प्रोग्रामर्स को साथ एकल से अधिक | एकाधिक वंशानुक्रम प्रोग्रामर्स को साथ एकल से अधिक पूर्ण रूप से ऑर्थोगोनल पदानुक्रम का उपयोग करने की अनुमति देता है, जैसे कि कैट को कार्टून चरित्र और पालतू और स्तनपायी से प्रदान करने की अनुमति देना और उन सभी वर्गों के भीतर सुविधाओं तक पहुंच बनाना। | ||
== कार्यान्वयन == | == कार्यान्वयन == | ||
Line 30: | Line 30: | ||
-->एकाधिक वंशानुक्रम का समर्थन करने वाली भाषाओं में शामिल हैं: [[C++]], [[सामान्य लिस्प]] ([[कॉमन लिस्प ऑब्जेक्ट सिस्टम]] (CLOS) के माध्यम से), [[EuLisp]] (EuLisp ऑब्जेक्ट सिस्टम TELOS के माध्यम से), [[कर्ल (प्रोग्रामिंग भाषा)]], [[डायलन (प्रोग्रामिंग भाषा)]], एफिल (प्रोग्रामिंग लैंग्वेज), लोगटॉक, ऑब्जेक्ट REXX, [[स्काला (प्रोग्रामिंग भाषा)]] (मिक्सिन क्लासेस के उपयोग के माध्यम से), [[OCaml]], [[पर्ल]], [[POP-11]], पायथन (प्रोग्रामिंग लैंग्वेज), R (प्रोग्रामिंग लैंग्वेज), [[राकू (प्रोग्रामिंग भाषा)]], और [[Tcl]] (बिल्ट-इन) 8.6 से या पिछले संस्करणों में इंक्रीमेंटल Tcl ([[Incr Tcl]]) के माध्यम से<ref>{{Cite web|url=http://blog.tcl.tk/62|title=incr Tcl|website=blog.tcl.tk|access-date=2020-04-14}}</ref><ref>{{Cite web|url=https://www2.lib.uchicago.edu/keith/tcl-course/|title=Introduction to the Tcl Programming Language|website=www2.lib.uchicago.edu|access-date=2020-04-14}}</ref>). | -->एकाधिक वंशानुक्रम का समर्थन करने वाली भाषाओं में शामिल हैं: [[C++]], [[सामान्य लिस्प]] ([[कॉमन लिस्प ऑब्जेक्ट सिस्टम]] (CLOS) के माध्यम से), [[EuLisp]] (EuLisp ऑब्जेक्ट सिस्टम TELOS के माध्यम से), [[कर्ल (प्रोग्रामिंग भाषा)]], [[डायलन (प्रोग्रामिंग भाषा)]], एफिल (प्रोग्रामिंग लैंग्वेज), लोगटॉक, ऑब्जेक्ट REXX, [[स्काला (प्रोग्रामिंग भाषा)]] (मिक्सिन क्लासेस के उपयोग के माध्यम से), [[OCaml]], [[पर्ल]], [[POP-11]], पायथन (प्रोग्रामिंग लैंग्वेज), R (प्रोग्रामिंग लैंग्वेज), [[राकू (प्रोग्रामिंग भाषा)]], और [[Tcl]] (बिल्ट-इन) 8.6 से या पिछले संस्करणों में इंक्रीमेंटल Tcl ([[Incr Tcl]]) के माध्यम से<ref>{{Cite web|url=http://blog.tcl.tk/62|title=incr Tcl|website=blog.tcl.tk|access-date=2020-04-14}}</ref><ref>{{Cite web|url=https://www2.lib.uchicago.edu/keith/tcl-course/|title=Introduction to the Tcl Programming Language|website=www2.lib.uchicago.edu|access-date=2020-04-14}}</ref>). | ||
[[आईबीएम सिस्टम ऑब्जेक्ट मॉडल]] (एसओएम) रनटाइम एकाधिक वंशानुक्रम का समर्थन करता है, और एसओएम को लक्षित करने वाली कोई भी प्रोग्रामिंग भाषा कई आधारों से | [[आईबीएम सिस्टम ऑब्जेक्ट मॉडल]] (एसओएम) रनटाइम एकाधिक वंशानुक्रम का समर्थन करता है, और एसओएम को लक्षित करने वाली कोई भी प्रोग्रामिंग भाषा कई आधारों से उत्तराधिकार में मिली नई एसओएम कक्षाओं को प्रारम्भ कर सकती है। | ||
कुछ ऑब्जेक्ट-ओरिएंटेड लैंग्वेज, जैसे कि [[स्विफ्ट (प्रोग्रामिंग भाषा)]], [[जावा (प्रोग्रामिंग भाषा)]], [[फोरट्रान]] अपने 2003 के संशोधन के बाद , सी #, और [[रूबी (प्रोग्रामिंग भाषा)]] सिंगल इनहेरिटेंस को | कुछ ऑब्जेक्ट-ओरिएंटेड लैंग्वेज, जैसे कि [[स्विफ्ट (प्रोग्रामिंग भाषा)]], [[जावा (प्रोग्रामिंग भाषा)]], [[फोरट्रान]] अपने 2003 के संशोधन के बाद , सी #, और [[रूबी (प्रोग्रामिंग भाषा)]] सिंगल इनहेरिटेंस को प्रारम्भ करती हैं, हालांकि प्रोटोकॉल (ऑब्जेक्ट- उन्मुख प्रोग्रामिंग), या इंटरफेस, सच्चे एकाधिक उत्तराधिकार की कुछ कार्यक्षमता प्रदान करते हैं। | ||
[[PHP|पीएचपी]] विशिष्ट विधि कार्यान्वयनों को इनहेरिट करने के लिए विशेषता वर्गों का उपयोग करती है। रूबी (प्रोग्रामिंग लैंग्वेज) कई | [[PHP|पीएचपी]] विशिष्ट विधि कार्यान्वयनों को इनहेरिट करने के लिए विशेषता वर्गों का उपयोग करती है। रूबी (प्रोग्रामिंग लैंग्वेज) कई उपाये को इनहेरिट करने के लिए [[मॉड्यूलर प्रोग्रामिंग]] का उपयोग करती है। | ||
== हीरे की समस्या == | == हीरे की समस्या == | ||
[[File:Diamond inheritance.svg|thumb|right|डायमंड क्लास इनहेरिटेंस डायग्राम।]]हीरे की समस्या (कभी-कभी मौत का घातक हीरा कहा जाता है<ref>{{cite web | last = Martin | first = Robert C. | author-link = Robert Cecil Martin | date = 1997-03-09 | title = Java and C++: A critical comparison | url = http://objectmentor.com/resources/articles/javacpp.pdf|format=PDF|website=Objectmentor.com|access-date=2016-10-21|archive-url=https://web.archive.org/web/20051024230813/http://www.objectmentor.com/resources/articles/javacpp.pdf|archive-date=2005-10-24}}</ref>) ऐसी अस्पष्टता है जो तब उत्पन्न होती है जब दो वर्ग बी और सी ए से प्राप्त होते हैं, और वर्ग डी बी और सी दोनों से प्राप्त होता है। यदि ए में कोई विधि है कि बी और सी में विधि ओवरराइडिंग (प्रोग्रामिंग) है, और डी इसे ओवरराइड नहीं करता है , तो विधि का कौन सा संस्करण D इनहेरिट करता है: B का, या C का? | [[File:Diamond inheritance.svg|thumb|right|डायमंड क्लास इनहेरिटेंस डायग्राम।]]हीरे की समस्या (कभी-कभी मौत का घातक हीरा कहा जाता है<ref>{{cite web | last = Martin | first = Robert C. | author-link = Robert Cecil Martin | date = 1997-03-09 | title = Java and C++: A critical comparison | url = http://objectmentor.com/resources/articles/javacpp.pdf|format=PDF|website=Objectmentor.com|access-date=2016-10-21|archive-url=https://web.archive.org/web/20051024230813/http://www.objectmentor.com/resources/articles/javacpp.pdf|archive-date=2005-10-24}}</ref>) ऐसी अस्पष्टता है जो तब उत्पन्न होती है जब दो वर्ग बी और सी ए से प्राप्त होते हैं, और वर्ग डी बी और सी दोनों से प्राप्त होता है। यदि ए में कोई विधि है कि बी और सी में विधि ओवरराइडिंग (प्रोग्रामिंग) है, और डी इसे ओवरराइड नहीं करता है , तो विधि का कौन सा संस्करण D इनहेरिट करता है: B का, या C का? | ||
उदाहरण के लिए, [[ग्राफिकल यूज़र इंटरफ़ेस]] [[सॉफ्टवेयर डेवलपमेंट]] के संदर्भ में, वर्ग <code>Button</code> दोनों वर्गों से | उदाहरण के लिए, [[ग्राफिकल यूज़र इंटरफ़ेस]] [[सॉफ्टवेयर डेवलपमेंट]] के संदर्भ में, वर्ग <code>Button</code> दोनों वर्गों से उत्तराधिकार में मिल सकता है <code>Rectangle</code> (उपस्थिति के लिए) और <code>Clickable</code> (कार्यक्षमता/इनपुट हैंडलिंग के लिए), और <code>Rectangle</code> और <code>Clickable</code> दोनों से उत्तराधिकार में मिला है <code>Object</code>वर्ग। अब यदि <code>equals</code> विधि के लिए कहा जाता है <code>Button</code> object और इसमें ऐसी कोई विधि नहीं है <code>Button</code> क्लास लेकिन ओवरराइड है <code>equals</code> विधि में <code>Rectangle</code> या <code>Clickable</code> (या दोनों), किस विधि को अंततः बुलाया जाना चाहिए? | ||
इस स्थिति में वर्ग वंशानुक्रम आरेख के आकार के कारण इसे हीरे की समस्या कहा जाता है। इस मामले में,वर्ग ए शीर्ष पर है, बी और सी दोनों अलग-अलग इसके नीचे हैं, और डी दोनों को एकल साथ जोड़कर हीरे की आकृति बनाता है। | इस स्थिति में वर्ग वंशानुक्रम आरेख के आकार के कारण इसे हीरे की समस्या कहा जाता है। इस मामले में,वर्ग ए शीर्ष पर है, बी और सी दोनों अलग-अलग इसके नीचे हैं, और डी दोनों को एकल साथ जोड़कर हीरे की आकृति बनाता है। | ||
Line 47: | Line 47: | ||
बार-बार वंशानुक्रम की इन समस्याओं से निपटने के लिए भाषाओं के अलग-अलग तरीके हैं। | बार-बार वंशानुक्रम की इन समस्याओं से निपटने के लिए भाषाओं के अलग-अलग तरीके हैं। | ||
* सी शार्प (प्रोग्रामिंग लैंग्वेज) | सी # (सी # 8.0 के बाद से) डिफ़ॉल्ट इंटरफ़ेस विधि कार्यान्वयन की अनुमति देता है, जिससे एकल वर्ग बनता है <code>A</code>, इंटरफेस | * सी शार्प (प्रोग्रामिंग लैंग्वेज) | सी # (सी # 8.0 के बाद से) डिफ़ॉल्ट इंटरफ़ेस विधि कार्यान्वयन की अनुमति देता है, जिससे एकल वर्ग बनता है <code>A</code>, इंटरफेस प्रारम्भ करना <code>Ia</code> और <code>Ib</code> डिफ़ॉल्ट कार्यान्वयन वाले समान उपाये के साथ, एकल ही हस्ताक्षर के साथ दो "उत्तराधिकार में मिली" विधियाँ, जिससे हीरे की समस्या होती है। इसे या तो होने से कम किया जाता है <code>A</code> विधि को स्वयं प्रारम्भ करने के लिए, इसलिए अस्पष्टता को दूर करना, या कॉल करने वाले को पहले कास्ट करने के लिए मजबूर करना <code>A</code> उस विधि के डिफ़ॉल्ट कार्यान्वयन का उपयोग करने के लिए उचित इंटरफ़ेस पर आपत्ति करें उदाहरण के लिए<code>((Ia) aInstance).Method)है|</code> | ||
* डिफ़ॉल्ट रूप से C++ प्रत्येक वंशानुक्रम पथ का अलग से अनुसरण करता है, इसलिए a <code>D</code> वस्तु में वास्तव में दो अलग-अलग होंगे <code>A</code> वस्तुओं, और <code>A</code>के सदस्यों का उपयोग ठीक से योग्य होना चाहिए। यदि से | * डिफ़ॉल्ट रूप से C++ प्रत्येक वंशानुक्रम पथ का अलग से अनुसरण करता है, इसलिए a <code>D</code> वस्तु में वास्तव में दो अलग-अलग होंगे <code>A</code> वस्तुओं, और <code>A</code>के सदस्यों का उपयोग ठीक से योग्य होना चाहिए। यदि से उत्तराधिकार <code>A</code> को <code>B</code> और से उत्तराधिकार <code>A</code> को <code>C</code> दोनों चिह्नित हैं<code>virtual</code>(उदाहरण के लिए,<code>class B : virtual public A</code>), C++ केवल एकल बनाने के लिए विशेष ध्यान रखता है <code>A</code>के सदस्यों का उपयोग करता है सही ढंग से काम करते हैं। यदि वर्चुअल इनहेरिटेंस और नॉनवर्चुअल इनहेरिटेंस को मिलाया जाता है, तो एकल ही वर्चुअल होता है <code>A</code>, और एकल गैर-आभासी <code>A</code> प्रत्येक गैर-वर्चुअल इनहेरिटेंस पथ के लिए <code>A</code>. C ++ को स्पष्ट रूप से यह बताने की आवश्यकता है कि किस मूल वर्ग का उपयोग किया जाना है, अर्थात। <code>Worker::Human.Age</code>. सी ++ स्पष्ट दोहराया उत्तराधिकार का समर्थन नहीं करता है क्योंकि सुपरक्लास का उपयोग करने के लिए अर्हता प्राप्त करने का कोई तरीका नहीं होगा (यानी कक्षा एकल से अधिक बार व्युत्पन्न सूची में दिखाई देती है [वर्ग कुत्ता: सार्वजनिक पशु, पशु])। C++ वर्चुअल इनहेरिटेंस मैकेनिज्म के माध्यम से मल्टीपल क्लास के सिंगल इंस्टेंस को भी बनाने की अनुमति देता है (यानी। <code>Worker::Human</code> और <code>Musician::Human</code> उसी वस्तु का संदर्भ देगा)। | ||
* कॉमन लिस्प कॉमन लिस्प ऑब्जेक्ट सिस्टम उचित डिफ़ॉल्ट व्यवहार और इसे ओवरराइड करने की क्षमता दोनों प्रदान करने का प्रयास करता है। डिफ़ॉल्ट रूप से, इसे सीधे शब्दों में कहें तो विधियों को क्रमबद्ध किया जाता है <code>D,B,C,A</code>, जब बी को क्लास की परिभाषा में सी) से पहले लिखा जाता है। सबसे विशिष्ट तर्क वर्गों वाली विधि को चुना गया है (D>(B,C)>A); फिर उस क्रम में जिसमें उपवर्ग परिभाषा (बी> सी) में मूल वर्गों का नाम दिया गया है। हालाँकि, प्रोग्रामर एकल विशिष्ट विधि रिज़ॉल्यूशन ऑर्डर देकर या विधियों के संयोजन के लिए एकल नियम बताकर इसे ओवरराइड कर सकता है। इसे मेथड कॉम्बिनेशन कहा जाता है, जिसे पूरी तरह से नियंत्रित किया जा सकता है। एमओपी ([[metaobject]] प्रोटोकॉल) सिस्टम की स्थिरता को प्रभावित किए बिना इनहेरिटेंस, [[गतिशील प्रेषण]], क्लास इंस्टेंटेशन और अन्य आंतरिक तंत्र को संशोधित करने के साधन भी प्रदान करता है। | * कॉमन लिस्प कॉमन लिस्प ऑब्जेक्ट सिस्टम उचित डिफ़ॉल्ट व्यवहार और इसे ओवरराइड करने की क्षमता दोनों प्रदान करने का प्रयास करता है। डिफ़ॉल्ट रूप से, इसे सीधे शब्दों में कहें तो विधियों को क्रमबद्ध किया जाता है <code>D,B,C,A</code>, जब बी को क्लास की परिभाषा में सी) से पहले लिखा जाता है। सबसे विशिष्ट तर्क वर्गों वाली विधि को चुना गया है (D>(B,C)>A); फिर उस क्रम में जिसमें उपवर्ग परिभाषा (बी> सी) में मूल वर्गों का नाम दिया गया है। हालाँकि, प्रोग्रामर एकल विशिष्ट विधि रिज़ॉल्यूशन ऑर्डर देकर या विधियों के संयोजन के लिए एकल नियम बताकर इसे ओवरराइड कर सकता है। इसे मेथड कॉम्बिनेशन कहा जाता है, जिसे पूरी तरह से नियंत्रित किया जा सकता है। एमओपी ([[metaobject]] प्रोटोकॉल) सिस्टम की स्थिरता को प्रभावित किए बिना इनहेरिटेंस, [[गतिशील प्रेषण]], क्लास इंस्टेंटेशन और अन्य आंतरिक तंत्र को संशोधित करने के साधन भी प्रदान करता है। | ||
* कर्ल (प्रोग्रामिंग लैंग्वेज) केवल उन वर्गों को अनुमति देता है जिन्हें स्पष्ट रूप से साझा के रूप में चिह्नित किया जाता है ताकि वे बार-बार | * कर्ल (प्रोग्रामिंग लैंग्वेज) केवल उन वर्गों को अनुमति देता है जिन्हें स्पष्ट रूप से साझा के रूप में चिह्नित किया जाता है ताकि वे बार-बार उत्तराधिकार में मिलें। साझा कक्षाओं को कक्षा में प्रत्येक नियमित निर्माता (कंप्यूटर विज्ञान) के लिए एकल द्वितीयक निर्माता को परिभाषित करना चाहिए। नियमित कंस्ट्रक्टर को पहली बार कहा जाता है कि साझा वर्ग के लिए राज्य को एकल उपवर्ग निर्माता के माध्यम से आरंभ किया जाता है, और अन्य सभी उपवर्गों के लिए द्वितीयक निर्माता को प्रारम्भ किया जाएगा। | ||
* एफिल (प्रोग्रामिंग लैंग्वेज) में, पूर्वजों की विशेषताओं को चुनिंदा और नाम बदलने के निर्देशों के साथ स्पष्ट रूप से चुना जाता है। यह आधार वर्ग की सुविधाओं को उसके वंशजों के | * एफिल (प्रोग्रामिंग लैंग्वेज) में, पूर्वजों की विशेषताओं को चुनिंदा और नाम बदलने के निर्देशों के साथ स्पष्ट रूप से चुना जाता है। यह आधार वर्ग की सुविधाओं को उसके वंशजों के मध्य साझा करने या उनमें से प्रत्येक को आधार वर्ग की एकल अलग प्रति देने की अनुमति देता है। एफिल पूर्वज वर्गों से उत्तराधिकार में मिली सुविधाओं को स्पष्ट रूप से जोड़ने या अलग करने की अनुमति देता है। अगर सुविधाओं का नाम और कार्यान्वयन एकल जैसा है, तो एफिल स्वचालित रूप से सुविधाओं में शामिल हो जाएगा। वर्ग लेखक के पास उन्हें अलग करने के लिए उत्तराधिकार में मिली सुविधाओं का नाम बदलने का विकल्प होता है। एफिल विकास में बहु वंशानुक्रम एकल सामान्य घटना है; डेटा संरचनाओं और एल्गोरिदम की व्यापक रूप से उपयोग की जाने वाली एफिलबेस लाइब्रेरी में अधिकांश प्रभावी कक्षाएं, उदाहरण के लिए, दो या दो से अधिक माता-पिता हैं।<ref>{{cite web|url=http://www.ecma-international.org/publications/standards/Ecma-367.htm|title=Standard ECMA-367|website=Ecma-international.org|access-date=2016-10-21}}</ref> | ||
* [[जाओ (प्रोग्रामिंग भाषा)]] संकलन समय पर हीरे की समस्या को रोकता है। अगर एकल संरचना <code>D</code> दो संरचनाओं को एम्बेड करता है <code>B</code> और <code>C</code> जिसमें दोनों का एकल तरीका है <code>F()</code>, इस प्रकार एकल इंटरफ़ेस को संतुष्ट करता है <code>A</code>, संकलक अस्पष्ट चयनकर्ता के बारे में शिकायत करेगा यदि <code>D.F()</code> कहा जाता है, या यदि का एकल उदाहरण <code>D</code> प्रकार के एकल चर को सौंपा गया है <code>A</code>. <code>B</code> और <code>C</code>के | * [[जाओ (प्रोग्रामिंग भाषा)]] संकलन समय पर हीरे की समस्या को रोकता है। अगर एकल संरचना <code>D</code> दो संरचनाओं को एम्बेड करता है <code>B</code> और <code>C</code> जिसमें दोनों का एकल तरीका है <code>F()</code>, इस प्रकार एकल इंटरफ़ेस को संतुष्ट करता है <code>A</code>, संकलक अस्पष्ट चयनकर्ता के बारे में शिकायत करेगा यदि <code>D.F()</code> कहा जाता है, या यदि का एकल उदाहरण <code>D</code> प्रकार के एकल चर को सौंपा गया है <code>A</code>. <code>B</code> और <code>C</code>के उपाये को स्पष्ट रूप से कहा जा सकता है <code>D.B.F()</code> या <code>D.C.F()</code>. | ||
* जावा (प्रोग्रामिंग भाषा) 8 इंटरफेस पर डिफ़ॉल्ट | * जावा (प्रोग्रामिंग भाषा) 8 इंटरफेस पर डिफ़ॉल्ट उपाये का परिचय देता है। अगर <code>A,B,C</code> इंटरफेस हैं, <code>B,C</code> क्या प्रत्येक एकल [[सार विधि]] के ललिए अलग कार्यान्वयन प्रदान कर सकता है <code>A</code>, हीरे की समस्या पैदा कर रहा है। कोई भी वर्ग <code>D</code> विधि को फिर से प्रारम्भ करना चाहिए (जिसका शरीर सुपर कार्यान्वयन में से किसी एकल को कॉल अग्रेषित कर सकता है), या अस्पष्टता को संकलन त्रुटि के रूप में खारिज कर दिया जाएगा।<ref>{{cite web|url=http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html|title=State of the Lambda|website=Cr.openjdk.java.net|access-date=2016-10-21}}</ref> जावा 8 से पहले, जावा डायमंड प्रॉब्लम रिस्क के अधीन नहीं था, क्योंकि यह मल्टीपल इनहेरिटेंस का समर्थन नहीं करता था और इंटरफ़ेस डिफ़ॉल्ट तरीके उपलब्ध नहीं थे। | ||
* वर्जन 1.2 में JavaFX स्क्रिप्ट मिक्सिन्स के उपयोग के माध्यम से मल्टीपल इनहेरिटेंस की अनुमति देता है। विरोध के मामले में, संकलक अस्पष्ट चर या फ़ंक्शन के प्रत्यक्ष उपयोग को प्रतिबंधित करता है। प्रत्येक | * वर्जन 1.2 में JavaFX स्क्रिप्ट मिक्सिन्स के उपयोग के माध्यम से मल्टीपल इनहेरिटेंस की अनुमति देता है। विरोध के मामले में, संकलक अस्पष्ट चर या फ़ंक्शन के प्रत्यक्ष उपयोग को प्रतिबंधित करता है। प्रत्येक उत्तराधिकार में मिले सदस्य को अभी भी वस्तु को ब्याज के मिश्रण में डालकर पहुँचा जा सकता है, उदाहरण के लिए <code>(individual as Person).printInfo();</code>. | ||
* [[कोटलिन (प्रोग्रामिंग भाषा)]] इंटरफ़ेस के कई वंशानुक्रम की अनुमति देता है, हालाँकि, डायमंड प्रॉब्लम परिदृश्य में, चाइल्ड क्लास को उस विधि को ओवरराइड करना चाहिए जो इनहेरिटेंस संघर्ष का कारण बनती है और निर्दिष्ट करती है कि किस पैरेंट क्लास कार्यान्वयन का उपयोग किया जाना चाहिए। उदाहरण के लिए <code> super<ChosenParentInterface>.someMethod()</code> | * [[कोटलिन (प्रोग्रामिंग भाषा)]] इंटरफ़ेस के कई वंशानुक्रम की अनुमति देता है, हालाँकि, डायमंड प्रॉब्लम परिदृश्य में, चाइल्ड क्लास को उस विधि को ओवरराइड करना चाहिए जो इनहेरिटेंस संघर्ष का कारण बनती है और निर्दिष्ट करती है कि किस पैरेंट क्लास कार्यान्वयन का उपयोग किया जाना चाहिए। उदाहरण के लिए <code> super<ChosenParentInterface>.someMethod()</code> | ||
* लॉगटॉक इंटरफ़ेस और कार्यान्वयन बहु- | * लॉगटॉक इंटरफ़ेस और कार्यान्वयन बहु-उत्तराधिकार दोनों का समर्थन करता है, विधि उपनामों की घोषणा की अनुमति देता है जो नाम बदलने और उन विधियों तक पहुंच प्रदान करता है जो डिफ़ॉल्ट संघर्ष समाधान तंत्र द्वारा नकाबपोश होंगे। | ||
* OCaml में, वर्ग परिभाषा के मुख्य भाग में पैरेंट क्लास को अलग-अलग निर्दिष्ट किया जाता है। विधियों (और विशेषताओं) को उसी क्रम में | * OCaml में, वर्ग परिभाषा के मुख्य भाग में पैरेंट क्लास को अलग-अलग निर्दिष्ट किया जाता है। विधियों (और विशेषताओं) को उसी क्रम में उत्तराधिकार में मिला है, जिसमें प्रत्येक नई उत्तराधिकार विधि किसी भी मौजूदा विधियों को ओवरराइड कर रही है। अस्पष्टता के तहत उपयोग करने के लिए किस विधि कार्यान्वयन को हल करने के लिए ओकैमल कक्षा उत्तराधिकार सूची की अंतिम मिलान परिभाषा चुनता है। डिफ़ॉल्ट व्यवहार को ओवरराइड करने के लिए, वांछित वर्ग परिभाषा के साथ विधि कॉल को योग्यता प्राप्त होती है। | ||
* पर्ल एकल आदेशित सूची के रूप में इनहेरिट करने के लिए कक्षाओं की सूची का उपयोग करता है। कंपाइलर पहली विधि का उपयोग करता है जो इसे सुपरक्लास सूची की [[गहराई-पहली खोज]] या कक्षा पदानुक्रम के सी 3 रैखिकरण का उपयोग करके मिलती है। विभिन्न एकल्सटेंशन वैकल्पिक वर्ग संरचना योजनाएँ प्रदान करते हैं। वंशानुक्रम का क्रम वर्ग शब्दार्थ को प्रभावित करता है। उपरोक्त अस्पष्टता में, class <code>B</code> और उसके पूर्वजों की कक्षा से पहले जाँच की जाएगी <code>C</code> और उसके पूर्वज, इसलिए में विधि <code>A</code> के माध्यम से | * पर्ल एकल आदेशित सूची के रूप में इनहेरिट करने के लिए कक्षाओं की सूची का उपयोग करता है। कंपाइलर पहली विधि का उपयोग करता है जो इसे सुपरक्लास सूची की [[गहराई-पहली खोज]] या कक्षा पदानुक्रम के सी 3 रैखिकरण का उपयोग करके मिलती है। विभिन्न एकल्सटेंशन वैकल्पिक वर्ग संरचना योजनाएँ प्रदान करते हैं। वंशानुक्रम का क्रम वर्ग शब्दार्थ को प्रभावित करता है। उपरोक्त अस्पष्टता में, class <code>B</code> और उसके पूर्वजों की कक्षा से पहले जाँच की जाएगी <code>C</code> और उसके पूर्वज, इसलिए में विधि <code>A</code> के माध्यम से उत्तराधिकार में मिलेगा <code>B</code>. इसे Io (प्रोग्रामिंग लैंग्वेज) और [[Picolisp]] के साथ शेयर किया जाता है। पर्ल में, इस व्यवहार को का उपयोग करके ओवरराइड किया जा सकता है <code>mro</code> या अन्य मॉड्यूल C3 रैखिककरण या अन्य एल्गोरिदम का उपयोग करने के लिए।<ref>{{cite web|url=http://perldoc.perl.org/perlobj.html#Method-Resolution-Order |title=perlobj |website=perldoc.perl.org |access-date=2016-10-21}}</ref> | ||
* पायथन (प्रोग्रामिंग लैंग्वेज) में पर्ल के समान संरचना है, लेकिन, पर्ल के विपरीत, इसे भाषा के वाक्य-विन्यास में शामिल करता है। वंशानुक्रम का क्रम वर्ग शब्दार्थ को प्रभावित करता है। पायथन को नई शैली की कक्षाओं की शुरूआत पर इससे निपटना पड़ा, जिनमें से सभी का एकल सामान्य पूर्वज है, <code>object</code>. पायथन C3 रैखिककरण (या मेथड रेज़ोल्यूशन ऑर्डर (एमआरओ) एल्गोरिथम का उपयोग करके कक्षाओं की एकल सूची बनाता है। वह एल्गोरिथ्म दो बाधाओं को | * पायथन (प्रोग्रामिंग लैंग्वेज) में पर्ल के समान संरचना है, लेकिन, पर्ल के विपरीत, इसे भाषा के वाक्य-विन्यास में शामिल करता है। वंशानुक्रम का क्रम वर्ग शब्दार्थ को प्रभावित करता है। पायथन को नई शैली की कक्षाओं की शुरूआत पर इससे निपटना पड़ा, जिनमें से सभी का एकल सामान्य पूर्वज है, <code>object</code>. पायथन C3 रैखिककरण (या मेथड रेज़ोल्यूशन ऑर्डर (एमआरओ) एल्गोरिथम का उपयोग करके कक्षाओं की एकल सूची बनाता है। वह एल्गोरिथ्म दो बाधाओं को प्रारम्भ करता है: बच्चे अपने माता-पिता से पहले और यदि एकल वर्ग कई वर्गों से उत्तराधिकार में मिलता है, तो उन्हें आधार वर्गों के टपल में निर्दिष्ट क्रम में रखा जाता है (हालांकि इस मामले में, वंशानुक्रम ग्राफ में उच्च कुछ वर्ग निम्न वर्गों से पहले हो सकते हैं) लेखाचित्र<ref>{{cite web|author=Abstract |url=https://www.python.org/download/releases/2.3/mro/#examples |title=The Python 2.3 Method Resolution Order |website=Python.org |access-date=2016-10-21}}</ref>). इस प्रकार, विधि संकल्प क्रम है: <code>D</code>, <code>B</code>, <code>C</code>, <code>A</code>.<ref>{{cite web|url=https://www.python.org/download/releases/2.2.3/descrintro/#mro |title=Unifying types and classes in Python 2.2 |website=Python.org |access-date=2016-10-21}}</ref> | ||
* रूबी (प्रोग्रामिंग लैंग्वेज) कक्षाओं में वास्तव में एकल माता-पिता होते हैं, लेकिन कई मॉड्यूल से भी प्राप्त हो सकते हैं; माणिक वर्ग की परिभाषाओं को निष्पादित किया जाता है, और एकल विधि की (पुनः) परिभाषा निष्पादन के समय पहले से मौजूद किसी भी परिभाषा को अस्पष्ट करती है। रनटाइम मेटाप्रोग्रामिंग की अनुपस्थिति में इसमें लगभग वही शब्दार्थ है जो सबसे सही गहराई के पहले रिज़ॉल्यूशन के रूप में है। | * रूबी (प्रोग्रामिंग लैंग्वेज) कक्षाओं में वास्तव में एकल माता-पिता होते हैं, लेकिन कई मॉड्यूल से भी प्राप्त हो सकते हैं; माणिक वर्ग की परिभाषाओं को निष्पादित किया जाता है, और एकल विधि की (पुनः) परिभाषा निष्पादन के समय पहले से मौजूद किसी भी परिभाषा को अस्पष्ट करती है। रनटाइम मेटाप्रोग्रामिंग की अनुपस्थिति में इसमें लगभग वही शब्दार्थ है जो सबसे सही गहराई के पहले रिज़ॉल्यूशन के रूप में है। | ||
* स्काला (प्रोग्रामिंग लैंग्वेज) लक्षणों के कई तात्कालिकता की अनुमति देता है, जो वर्ग पदानुक्रम और विशेषता पदानुक्रम के | * स्काला (प्रोग्रामिंग लैंग्वेज) लक्षणों के कई तात्कालिकता की अनुमति देता है, जो वर्ग पदानुक्रम और विशेषता पदानुक्रम के मध्य अंतर जोड़कर कई वंशानुक्रम की अनुमति देता है। एकलल वर्ग केवल एकलल वर्ग से उत्तराधिकारी हो सकता है, लेकिन वांछित के रूप में कई लक्षणों को मिश्रित कर सकता है। स्कैला परिणामी सूची में प्रत्येक मॉड्यूल की अंतिम घटना को छोड़कर सभी को समाप्त करने से पहले विस्तारित 'लक्षणों' की राइट-फर्स्ट डेप्थ-फर्स्ट सर्च का उपयोग करके विधि नामों को हल करता है। तो, संकल्प आदेश है: [<code>D</code>, <code>C</code>, <code>A</code>, <code>B</code>, <code>A</code>], जो कम हो जाता है [<code>D</code>, <code>C</code>, <code>B</code>, <code>A</code>]। | ||
* टीसीएल कई मूल वर्गों की अनुमति देता है; वर्ग घोषणा में विनिर्देशन का क्रम C3 रैखिककरण एल्गोरिथम का उपयोग करने वाले सदस्यों के लिए नाम रिज़ॉल्यूशन को प्रभावित करता है।<ref>{{cite web|url=http://www.tcl.tk/man/itcl3.1/class.n.html |title=Manpage of class |website=Tcl.tk |date=1999-11-16 |access-date=2016-10-21}}</ref> | * टीसीएल कई मूल वर्गों की अनुमति देता है; वर्ग घोषणा में विनिर्देशन का क्रम C3 रैखिककरण एल्गोरिथम का उपयोग करने वाले सदस्यों के लिए नाम रिज़ॉल्यूशन को प्रभावित करता है।<ref>{{cite web|url=http://www.tcl.tk/man/itcl3.1/class.n.html |title=Manpage of class |website=Tcl.tk |date=1999-11-16 |access-date=2016-10-21}}</ref> | ||
ऐसी भाषाएँ जो केवल एकलल वंशानुक्रम की अनुमति देती हैं, जहाँ एकलल वर्ग केवल एकल आधार वर्ग से प्राप्त हो सकता है, हीरे की समस्या नहीं है। इसका कारण यह है कि ऐसी भाषाओं में विधियों की पुनरावृत्ति या प्लेसमेंट की परवाह किए बिना वंशानुक्रम श्रृंखला में किसी भी स्तर पर किसी भी विधि का अधिकतम कार्यान्वयन होता है। आमतौर पर ये भाषाएँ कक्षाओं को जावा में [[इंटरफ़ेस (जावा)]] कहे जाने वाले कई प्रोटोकॉल (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) को | ऐसी भाषाएँ जो केवल एकलल वंशानुक्रम की अनुमति देती हैं, जहाँ एकलल वर्ग केवल एकल आधार वर्ग से प्राप्त हो सकता है, हीरे की समस्या नहीं है। इसका कारण यह है कि ऐसी भाषाओं में विधियों की पुनरावृत्ति या प्लेसमेंट की परवाह किए बिना वंशानुक्रम श्रृंखला में किसी भी स्तर पर किसी भी विधि का अधिकतम कार्यान्वयन होता है। आमतौर पर ये भाषाएँ कक्षाओं को जावा में [[इंटरफ़ेस (जावा)]] कहे जाने वाले कई प्रोटोकॉल (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) को प्रारम्भ करने की अनुमति देती हैं। ये प्रोटोकॉल विधियों को परिभाषित करते हैं लेकिन ठोस कार्यान्वयन प्रदान नहीं करते हैं। इस रणनीति का उपयोग [[ActionScript]], C Sharp (प्रोग्रामिंग लैंग्वेज) | C#, D (प्रोग्रामिंग लैंग्वेज),जावा (प्रोग्रामिंग लैंग्वेज), [[नेमर्ले]], [[वस्तु पास्कल]], [[उद्देश्य सी]], स्मॉलटॉक, स्विफ्ट (प्रोग्रामिंग लैंग्वेज) और पीएचपी प्रोग्रामिंग लैंग्वेज) द्वारा किया गया है। ).<ref>{{cite web|url=http://php.net/manual/en/language.oop5.interfaces.php |title=Object Interfaces - Manual |website=PHP.net |date=2007-07-04 |access-date=2016-10-21}}</ref> ये सभी भाषाएँ कक्षाओं को कई प्रोटोकॉल प्रारम्भ करने की अनुमति देती हैं। | ||
इसके अलावा, एडा (प्रोग्रामिंग लैंग्वेज), सी #, जावा, ऑब्जेक्ट पास्कल, ऑब्जेक्टिव-सी, स्विफ्ट और पीएचपी इंटरफेस के मल्टीपल-इनहेरिटेंस (ऑब्जेक्टिव-सी और स्विफ्ट में प्रोटोकॉल कहा जाता है) की अनुमति देते हैं। इंटरफेस सार आधार वर्गों की तरह हैं जो किसी भी व्यवहार को | इसके अलावा, एडा (प्रोग्रामिंग लैंग्वेज), सी #, जावा, ऑब्जेक्ट पास्कल, ऑब्जेक्टिव-सी, स्विफ्ट और पीएचपी इंटरफेस के मल्टीपल-इनहेरिटेंस (ऑब्जेक्टिव-सी और स्विफ्ट में प्रोटोकॉल कहा जाता है) की अनुमति देते हैं। इंटरफेस सार आधार वर्गों की तरह हैं जो किसी भी व्यवहार को प्रारम्भ किए बिना विधि हस्ताक्षर निर्दिष्ट करते हैं। ( शुद्ध इंटरफ़ेस जैसे कि जावा में संस्करण 7 तक इंटरफ़ेस में किसी भी कार्यान्वयन या उदाहरण डेटा की अनुमति नहीं देते हैं।) फिर भी, भले ही कई इंटरफेस ऐसी ही विधि हस्ताक्षर की घोषणा करते हैं, जैसे ही उस विधि को कहीं भी प्रारम्भ (परिभाषित) किया जाता है। उत्तराधिकार श्रृंखला, यह उस विधि के किसी भी कार्यान्वयन को इसके ऊपर की श्रृंखला में (इसके सुपरक्लास में) ओवरराइड करता है। इसलिए, उत्तराधिकार श्रृंखला में किसी भी स्तर पर, किसी भी विधि का अधिकतम एकल कार्यान्वयन हो सकता है। इस प्रकार, सिंगल-इनहेरिटेंस विधि कार्यान्वयन इंटरफेस के मल्टीपल-इनहेरिटेंस के साथ भी डायमंड प्रॉब्लम को प्रदर्शित नहीं करता है। जावा 8 और सी # 8 में इंटरफेस के लिए डिफ़ॉल्ट कार्यान्वयन की शुरुआत के साथ, डायमंड प्रॉब्लम उत्पन्न करना अभी भी संभव है, हालांकि यह केवल संकलन-समय त्रुटि के रूप में दिखाई देगा। | ||
{{see also|Comparison of C Sharp and Java#Explicit interface implementation}} | {{see also|Comparison of C Sharp and Java#Explicit interface implementation}} |
Revision as of 13:13, 20 February 2023
एकाधिक वंशानुक्रम कुछ ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग भाषा की ऐसी विशेषता है जिसमें ऑब्जेक्ट या क्लास (कंप्यूटर प्रोग्रामिंग) एकल से अधिक पैरेंट ऑब्जेक्ट या सुपरक्लास (कंप्यूटर साइंस) से वंशानुक्रम (वस्तु-उन्मुख प्रोग्रामिंग) कर सकता है। यह एकल वंशानुक्रम से भिन्न है, जहाँ एकल वस्तु या वर्ग केवल एकल विशेष वस्तु या वर्ग से प्राप्त हो सकता है।
एकाधिक वंशानुक्रम कई वर्षों से संदेहयुक्त विषय रहा है,[1][2] विरोधियों के साथ हीरे की समस्या जैसी स्थितियों में इसकी बढ़ी हुई जटिलता और अस्पष्टता की ओर संकेत करते हुए, जहां यह अस्पष्ट हो सकता है कि किस मूल वर्ग से विशेष विशेषता उत्तराधिकार में मिली है यदि एकल से अधिक मूल वर्ग उक्त विशेषता को प्रारम्भ करते हैं। वर्चुअल उत्तराधिकार का उपयोग करने सहित इसे विभिन्न उपाये से संबोधित किया जा सकता है।[3] अस्पष्टता को संबोधित करने के लिए ऑब्जेक्ट संरचना के वैकल्पिक उपाये जैसे मिश्रण और विशेषता (कंप्यूटर प्रोग्रामिंग) पर आधारित नहीं है।
विवरण
ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग (OOP) में, वंशानुक्रम दो वर्गों के मध्य एकल संबंध का वर्णन करता है जिसमें (चाइल्ड क्लास) वर्ग, पैरेंट क्लास को उप-वर्गित करता है। बच्चा माता-पिता की विधियों और विशेषताओं को उत्तराधिकार में प्राप्त करता है, जिससे भागीदारी में कार्यक्षमता की अनुमति मिलती है। उदाहरण के लिए, कोई चर वर्ग स्तनपायी बना सकता है जिसमें खाने, प्रजनन, आदि जैसी विशेषताएं हों फिर एकल चाइल्ड क्लास कैट को परिभाषित करें जो चूहों का पीछा करने जैसी नई सुविधाओं को जोड़ते हुए उन विशेषताओं को स्पष्ट रूप से प्रोग्राम किए बिना प्रदान करती है।
एकाधिक वंशानुक्रम प्रोग्रामर्स को साथ एकल से अधिक पूर्ण रूप से ऑर्थोगोनल पदानुक्रम का उपयोग करने की अनुमति देता है, जैसे कि कैट को कार्टून चरित्र और पालतू और स्तनपायी से प्रदान करने की अनुमति देना और उन सभी वर्गों के भीतर सुविधाओं तक पहुंच बनाना।
कार्यान्वयन
एकाधिक वंशानुक्रम का समर्थन करने वाली भाषाओं में शामिल हैं: C++, सामान्य लिस्प (कॉमन लिस्प ऑब्जेक्ट सिस्टम (CLOS) के माध्यम से), EuLisp (EuLisp ऑब्जेक्ट सिस्टम TELOS के माध्यम से), कर्ल (प्रोग्रामिंग भाषा), डायलन (प्रोग्रामिंग भाषा), एफिल (प्रोग्रामिंग लैंग्वेज), लोगटॉक, ऑब्जेक्ट REXX, स्काला (प्रोग्रामिंग भाषा) (मिक्सिन क्लासेस के उपयोग के माध्यम से), OCaml, पर्ल, POP-11, पायथन (प्रोग्रामिंग लैंग्वेज), R (प्रोग्रामिंग लैंग्वेज), राकू (प्रोग्रामिंग भाषा), और Tcl (बिल्ट-इन) 8.6 से या पिछले संस्करणों में इंक्रीमेंटल Tcl (Incr Tcl) के माध्यम से[4][5]).
आईबीएम सिस्टम ऑब्जेक्ट मॉडल (एसओएम) रनटाइम एकाधिक वंशानुक्रम का समर्थन करता है, और एसओएम को लक्षित करने वाली कोई भी प्रोग्रामिंग भाषा कई आधारों से उत्तराधिकार में मिली नई एसओएम कक्षाओं को प्रारम्भ कर सकती है।
कुछ ऑब्जेक्ट-ओरिएंटेड लैंग्वेज, जैसे कि स्विफ्ट (प्रोग्रामिंग भाषा), जावा (प्रोग्रामिंग भाषा), फोरट्रान अपने 2003 के संशोधन के बाद , सी #, और रूबी (प्रोग्रामिंग भाषा) सिंगल इनहेरिटेंस को प्रारम्भ करती हैं, हालांकि प्रोटोकॉल (ऑब्जेक्ट- उन्मुख प्रोग्रामिंग), या इंटरफेस, सच्चे एकाधिक उत्तराधिकार की कुछ कार्यक्षमता प्रदान करते हैं।
पीएचपी विशिष्ट विधि कार्यान्वयनों को इनहेरिट करने के लिए विशेषता वर्गों का उपयोग करती है। रूबी (प्रोग्रामिंग लैंग्वेज) कई उपाये को इनहेरिट करने के लिए मॉड्यूलर प्रोग्रामिंग का उपयोग करती है।
हीरे की समस्या
हीरे की समस्या (कभी-कभी मौत का घातक हीरा कहा जाता है[6]) ऐसी अस्पष्टता है जो तब उत्पन्न होती है जब दो वर्ग बी और सी ए से प्राप्त होते हैं, और वर्ग डी बी और सी दोनों से प्राप्त होता है। यदि ए में कोई विधि है कि बी और सी में विधि ओवरराइडिंग (प्रोग्रामिंग) है, और डी इसे ओवरराइड नहीं करता है , तो विधि का कौन सा संस्करण D इनहेरिट करता है: B का, या C का?
उदाहरण के लिए, ग्राफिकल यूज़र इंटरफ़ेस सॉफ्टवेयर डेवलपमेंट के संदर्भ में, वर्ग Button
दोनों वर्गों से उत्तराधिकार में मिल सकता है Rectangle
(उपस्थिति के लिए) और Clickable
(कार्यक्षमता/इनपुट हैंडलिंग के लिए), और Rectangle
और Clickable
दोनों से उत्तराधिकार में मिला है Object
वर्ग। अब यदि equals
विधि के लिए कहा जाता है Button
object और इसमें ऐसी कोई विधि नहीं है Button
क्लास लेकिन ओवरराइड है equals
विधि में Rectangle
या Clickable
(या दोनों), किस विधि को अंततः बुलाया जाना चाहिए?
इस स्थिति में वर्ग वंशानुक्रम आरेख के आकार के कारण इसे हीरे की समस्या कहा जाता है। इस मामले में,वर्ग ए शीर्ष पर है, बी और सी दोनों अलग-अलग इसके नीचे हैं, और डी दोनों को एकल साथ जोड़कर हीरे की आकृति बनाता है।
शमन
बार-बार वंशानुक्रम की इन समस्याओं से निपटने के लिए भाषाओं के अलग-अलग तरीके हैं।
- सी शार्प (प्रोग्रामिंग लैंग्वेज) | सी # (सी # 8.0 के बाद से) डिफ़ॉल्ट इंटरफ़ेस विधि कार्यान्वयन की अनुमति देता है, जिससे एकल वर्ग बनता है
A
, इंटरफेस प्रारम्भ करनाIa
औरIb
डिफ़ॉल्ट कार्यान्वयन वाले समान उपाये के साथ, एकल ही हस्ताक्षर के साथ दो "उत्तराधिकार में मिली" विधियाँ, जिससे हीरे की समस्या होती है। इसे या तो होने से कम किया जाता हैA
विधि को स्वयं प्रारम्भ करने के लिए, इसलिए अस्पष्टता को दूर करना, या कॉल करने वाले को पहले कास्ट करने के लिए मजबूर करनाA
उस विधि के डिफ़ॉल्ट कार्यान्वयन का उपयोग करने के लिए उचित इंटरफ़ेस पर आपत्ति करें उदाहरण के लिए((Ia) aInstance).Method)है|
- डिफ़ॉल्ट रूप से C++ प्रत्येक वंशानुक्रम पथ का अलग से अनुसरण करता है, इसलिए a
D
वस्तु में वास्तव में दो अलग-अलग होंगेA
वस्तुओं, औरA
के सदस्यों का उपयोग ठीक से योग्य होना चाहिए। यदि से उत्तराधिकारA
कोB
और से उत्तराधिकारA
कोC
दोनों चिह्नित हैंvirtual
(उदाहरण के लिए,class B : virtual public A
), C++ केवल एकल बनाने के लिए विशेष ध्यान रखता हैA
के सदस्यों का उपयोग करता है सही ढंग से काम करते हैं। यदि वर्चुअल इनहेरिटेंस और नॉनवर्चुअल इनहेरिटेंस को मिलाया जाता है, तो एकल ही वर्चुअल होता हैA
, और एकल गैर-आभासीA
प्रत्येक गैर-वर्चुअल इनहेरिटेंस पथ के लिएA
. C ++ को स्पष्ट रूप से यह बताने की आवश्यकता है कि किस मूल वर्ग का उपयोग किया जाना है, अर्थात।Worker::Human.Age
. सी ++ स्पष्ट दोहराया उत्तराधिकार का समर्थन नहीं करता है क्योंकि सुपरक्लास का उपयोग करने के लिए अर्हता प्राप्त करने का कोई तरीका नहीं होगा (यानी कक्षा एकल से अधिक बार व्युत्पन्न सूची में दिखाई देती है [वर्ग कुत्ता: सार्वजनिक पशु, पशु])। C++ वर्चुअल इनहेरिटेंस मैकेनिज्म के माध्यम से मल्टीपल क्लास के सिंगल इंस्टेंस को भी बनाने की अनुमति देता है (यानी।Worker::Human
औरMusician::Human
उसी वस्तु का संदर्भ देगा)। - कॉमन लिस्प कॉमन लिस्प ऑब्जेक्ट सिस्टम उचित डिफ़ॉल्ट व्यवहार और इसे ओवरराइड करने की क्षमता दोनों प्रदान करने का प्रयास करता है। डिफ़ॉल्ट रूप से, इसे सीधे शब्दों में कहें तो विधियों को क्रमबद्ध किया जाता है
D,B,C,A
, जब बी को क्लास की परिभाषा में सी) से पहले लिखा जाता है। सबसे विशिष्ट तर्क वर्गों वाली विधि को चुना गया है (D>(B,C)>A); फिर उस क्रम में जिसमें उपवर्ग परिभाषा (बी> सी) में मूल वर्गों का नाम दिया गया है। हालाँकि, प्रोग्रामर एकल विशिष्ट विधि रिज़ॉल्यूशन ऑर्डर देकर या विधियों के संयोजन के लिए एकल नियम बताकर इसे ओवरराइड कर सकता है। इसे मेथड कॉम्बिनेशन कहा जाता है, जिसे पूरी तरह से नियंत्रित किया जा सकता है। एमओपी (metaobject प्रोटोकॉल) सिस्टम की स्थिरता को प्रभावित किए बिना इनहेरिटेंस, गतिशील प्रेषण, क्लास इंस्टेंटेशन और अन्य आंतरिक तंत्र को संशोधित करने के साधन भी प्रदान करता है। - कर्ल (प्रोग्रामिंग लैंग्वेज) केवल उन वर्गों को अनुमति देता है जिन्हें स्पष्ट रूप से साझा के रूप में चिह्नित किया जाता है ताकि वे बार-बार उत्तराधिकार में मिलें। साझा कक्षाओं को कक्षा में प्रत्येक नियमित निर्माता (कंप्यूटर विज्ञान) के लिए एकल द्वितीयक निर्माता को परिभाषित करना चाहिए। नियमित कंस्ट्रक्टर को पहली बार कहा जाता है कि साझा वर्ग के लिए राज्य को एकल उपवर्ग निर्माता के माध्यम से आरंभ किया जाता है, और अन्य सभी उपवर्गों के लिए द्वितीयक निर्माता को प्रारम्भ किया जाएगा।
- एफिल (प्रोग्रामिंग लैंग्वेज) में, पूर्वजों की विशेषताओं को चुनिंदा और नाम बदलने के निर्देशों के साथ स्पष्ट रूप से चुना जाता है। यह आधार वर्ग की सुविधाओं को उसके वंशजों के मध्य साझा करने या उनमें से प्रत्येक को आधार वर्ग की एकल अलग प्रति देने की अनुमति देता है। एफिल पूर्वज वर्गों से उत्तराधिकार में मिली सुविधाओं को स्पष्ट रूप से जोड़ने या अलग करने की अनुमति देता है। अगर सुविधाओं का नाम और कार्यान्वयन एकल जैसा है, तो एफिल स्वचालित रूप से सुविधाओं में शामिल हो जाएगा। वर्ग लेखक के पास उन्हें अलग करने के लिए उत्तराधिकार में मिली सुविधाओं का नाम बदलने का विकल्प होता है। एफिल विकास में बहु वंशानुक्रम एकल सामान्य घटना है; डेटा संरचनाओं और एल्गोरिदम की व्यापक रूप से उपयोग की जाने वाली एफिलबेस लाइब्रेरी में अधिकांश प्रभावी कक्षाएं, उदाहरण के लिए, दो या दो से अधिक माता-पिता हैं।[7]
- जाओ (प्रोग्रामिंग भाषा) संकलन समय पर हीरे की समस्या को रोकता है। अगर एकल संरचना
D
दो संरचनाओं को एम्बेड करता हैB
औरC
जिसमें दोनों का एकल तरीका हैF()
, इस प्रकार एकल इंटरफ़ेस को संतुष्ट करता हैA
, संकलक अस्पष्ट चयनकर्ता के बारे में शिकायत करेगा यदिD.F()
कहा जाता है, या यदि का एकल उदाहरणD
प्रकार के एकल चर को सौंपा गया हैA
.B
औरC
के उपाये को स्पष्ट रूप से कहा जा सकता हैD.B.F()
याD.C.F()
. - जावा (प्रोग्रामिंग भाषा) 8 इंटरफेस पर डिफ़ॉल्ट उपाये का परिचय देता है। अगर
A,B,C
इंटरफेस हैं,B,C
क्या प्रत्येक एकल सार विधि के ललिए अलग कार्यान्वयन प्रदान कर सकता हैA
, हीरे की समस्या पैदा कर रहा है। कोई भी वर्गD
विधि को फिर से प्रारम्भ करना चाहिए (जिसका शरीर सुपर कार्यान्वयन में से किसी एकल को कॉल अग्रेषित कर सकता है), या अस्पष्टता को संकलन त्रुटि के रूप में खारिज कर दिया जाएगा।[8] जावा 8 से पहले, जावा डायमंड प्रॉब्लम रिस्क के अधीन नहीं था, क्योंकि यह मल्टीपल इनहेरिटेंस का समर्थन नहीं करता था और इंटरफ़ेस डिफ़ॉल्ट तरीके उपलब्ध नहीं थे। - वर्जन 1.2 में JavaFX स्क्रिप्ट मिक्सिन्स के उपयोग के माध्यम से मल्टीपल इनहेरिटेंस की अनुमति देता है। विरोध के मामले में, संकलक अस्पष्ट चर या फ़ंक्शन के प्रत्यक्ष उपयोग को प्रतिबंधित करता है। प्रत्येक उत्तराधिकार में मिले सदस्य को अभी भी वस्तु को ब्याज के मिश्रण में डालकर पहुँचा जा सकता है, उदाहरण के लिए
(individual as Person).printInfo();
. - कोटलिन (प्रोग्रामिंग भाषा) इंटरफ़ेस के कई वंशानुक्रम की अनुमति देता है, हालाँकि, डायमंड प्रॉब्लम परिदृश्य में, चाइल्ड क्लास को उस विधि को ओवरराइड करना चाहिए जो इनहेरिटेंस संघर्ष का कारण बनती है और निर्दिष्ट करती है कि किस पैरेंट क्लास कार्यान्वयन का उपयोग किया जाना चाहिए। उदाहरण के लिए
super<ChosenParentInterface>.someMethod()
- लॉगटॉक इंटरफ़ेस और कार्यान्वयन बहु-उत्तराधिकार दोनों का समर्थन करता है, विधि उपनामों की घोषणा की अनुमति देता है जो नाम बदलने और उन विधियों तक पहुंच प्रदान करता है जो डिफ़ॉल्ट संघर्ष समाधान तंत्र द्वारा नकाबपोश होंगे।
- OCaml में, वर्ग परिभाषा के मुख्य भाग में पैरेंट क्लास को अलग-अलग निर्दिष्ट किया जाता है। विधियों (और विशेषताओं) को उसी क्रम में उत्तराधिकार में मिला है, जिसमें प्रत्येक नई उत्तराधिकार विधि किसी भी मौजूदा विधियों को ओवरराइड कर रही है। अस्पष्टता के तहत उपयोग करने के लिए किस विधि कार्यान्वयन को हल करने के लिए ओकैमल कक्षा उत्तराधिकार सूची की अंतिम मिलान परिभाषा चुनता है। डिफ़ॉल्ट व्यवहार को ओवरराइड करने के लिए, वांछित वर्ग परिभाषा के साथ विधि कॉल को योग्यता प्राप्त होती है।
- पर्ल एकल आदेशित सूची के रूप में इनहेरिट करने के लिए कक्षाओं की सूची का उपयोग करता है। कंपाइलर पहली विधि का उपयोग करता है जो इसे सुपरक्लास सूची की गहराई-पहली खोज या कक्षा पदानुक्रम के सी 3 रैखिकरण का उपयोग करके मिलती है। विभिन्न एकल्सटेंशन वैकल्पिक वर्ग संरचना योजनाएँ प्रदान करते हैं। वंशानुक्रम का क्रम वर्ग शब्दार्थ को प्रभावित करता है। उपरोक्त अस्पष्टता में, class
B
और उसके पूर्वजों की कक्षा से पहले जाँच की जाएगीC
और उसके पूर्वज, इसलिए में विधिA
के माध्यम से उत्तराधिकार में मिलेगाB
. इसे Io (प्रोग्रामिंग लैंग्वेज) और Picolisp के साथ शेयर किया जाता है। पर्ल में, इस व्यवहार को का उपयोग करके ओवरराइड किया जा सकता हैmro
या अन्य मॉड्यूल C3 रैखिककरण या अन्य एल्गोरिदम का उपयोग करने के लिए।[9] - पायथन (प्रोग्रामिंग लैंग्वेज) में पर्ल के समान संरचना है, लेकिन, पर्ल के विपरीत, इसे भाषा के वाक्य-विन्यास में शामिल करता है। वंशानुक्रम का क्रम वर्ग शब्दार्थ को प्रभावित करता है। पायथन को नई शैली की कक्षाओं की शुरूआत पर इससे निपटना पड़ा, जिनमें से सभी का एकल सामान्य पूर्वज है,
object
. पायथन C3 रैखिककरण (या मेथड रेज़ोल्यूशन ऑर्डर (एमआरओ) एल्गोरिथम का उपयोग करके कक्षाओं की एकल सूची बनाता है। वह एल्गोरिथ्म दो बाधाओं को प्रारम्भ करता है: बच्चे अपने माता-पिता से पहले और यदि एकल वर्ग कई वर्गों से उत्तराधिकार में मिलता है, तो उन्हें आधार वर्गों के टपल में निर्दिष्ट क्रम में रखा जाता है (हालांकि इस मामले में, वंशानुक्रम ग्राफ में उच्च कुछ वर्ग निम्न वर्गों से पहले हो सकते हैं) लेखाचित्र[10]). इस प्रकार, विधि संकल्प क्रम है:D
,B
,C
,A
.[11] - रूबी (प्रोग्रामिंग लैंग्वेज) कक्षाओं में वास्तव में एकल माता-पिता होते हैं, लेकिन कई मॉड्यूल से भी प्राप्त हो सकते हैं; माणिक वर्ग की परिभाषाओं को निष्पादित किया जाता है, और एकल विधि की (पुनः) परिभाषा निष्पादन के समय पहले से मौजूद किसी भी परिभाषा को अस्पष्ट करती है। रनटाइम मेटाप्रोग्रामिंग की अनुपस्थिति में इसमें लगभग वही शब्दार्थ है जो सबसे सही गहराई के पहले रिज़ॉल्यूशन के रूप में है।
- स्काला (प्रोग्रामिंग लैंग्वेज) लक्षणों के कई तात्कालिकता की अनुमति देता है, जो वर्ग पदानुक्रम और विशेषता पदानुक्रम के मध्य अंतर जोड़कर कई वंशानुक्रम की अनुमति देता है। एकलल वर्ग केवल एकलल वर्ग से उत्तराधिकारी हो सकता है, लेकिन वांछित के रूप में कई लक्षणों को मिश्रित कर सकता है। स्कैला परिणामी सूची में प्रत्येक मॉड्यूल की अंतिम घटना को छोड़कर सभी को समाप्त करने से पहले विस्तारित 'लक्षणों' की राइट-फर्स्ट डेप्थ-फर्स्ट सर्च का उपयोग करके विधि नामों को हल करता है। तो, संकल्प आदेश है: [
D
,C
,A
,B
,A
], जो कम हो जाता है [D
,C
,B
,A
]। - टीसीएल कई मूल वर्गों की अनुमति देता है; वर्ग घोषणा में विनिर्देशन का क्रम C3 रैखिककरण एल्गोरिथम का उपयोग करने वाले सदस्यों के लिए नाम रिज़ॉल्यूशन को प्रभावित करता है।[12]
ऐसी भाषाएँ जो केवल एकलल वंशानुक्रम की अनुमति देती हैं, जहाँ एकलल वर्ग केवल एकल आधार वर्ग से प्राप्त हो सकता है, हीरे की समस्या नहीं है। इसका कारण यह है कि ऐसी भाषाओं में विधियों की पुनरावृत्ति या प्लेसमेंट की परवाह किए बिना वंशानुक्रम श्रृंखला में किसी भी स्तर पर किसी भी विधि का अधिकतम कार्यान्वयन होता है। आमतौर पर ये भाषाएँ कक्षाओं को जावा में इंटरफ़ेस (जावा) कहे जाने वाले कई प्रोटोकॉल (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) को प्रारम्भ करने की अनुमति देती हैं। ये प्रोटोकॉल विधियों को परिभाषित करते हैं लेकिन ठोस कार्यान्वयन प्रदान नहीं करते हैं। इस रणनीति का उपयोग ActionScript, C Sharp (प्रोग्रामिंग लैंग्वेज) | C#, D (प्रोग्रामिंग लैंग्वेज),जावा (प्रोग्रामिंग लैंग्वेज), नेमर्ले, वस्तु पास्कल, उद्देश्य सी, स्मॉलटॉक, स्विफ्ट (प्रोग्रामिंग लैंग्वेज) और पीएचपी प्रोग्रामिंग लैंग्वेज) द्वारा किया गया है। ).[13] ये सभी भाषाएँ कक्षाओं को कई प्रोटोकॉल प्रारम्भ करने की अनुमति देती हैं।
इसके अलावा, एडा (प्रोग्रामिंग लैंग्वेज), सी #, जावा, ऑब्जेक्ट पास्कल, ऑब्जेक्टिव-सी, स्विफ्ट और पीएचपी इंटरफेस के मल्टीपल-इनहेरिटेंस (ऑब्जेक्टिव-सी और स्विफ्ट में प्रोटोकॉल कहा जाता है) की अनुमति देते हैं। इंटरफेस सार आधार वर्गों की तरह हैं जो किसी भी व्यवहार को प्रारम्भ किए बिना विधि हस्ताक्षर निर्दिष्ट करते हैं। ( शुद्ध इंटरफ़ेस जैसे कि जावा में संस्करण 7 तक इंटरफ़ेस में किसी भी कार्यान्वयन या उदाहरण डेटा की अनुमति नहीं देते हैं।) फिर भी, भले ही कई इंटरफेस ऐसी ही विधि हस्ताक्षर की घोषणा करते हैं, जैसे ही उस विधि को कहीं भी प्रारम्भ (परिभाषित) किया जाता है। उत्तराधिकार श्रृंखला, यह उस विधि के किसी भी कार्यान्वयन को इसके ऊपर की श्रृंखला में (इसके सुपरक्लास में) ओवरराइड करता है। इसलिए, उत्तराधिकार श्रृंखला में किसी भी स्तर पर, किसी भी विधि का अधिकतम एकल कार्यान्वयन हो सकता है। इस प्रकार, सिंगल-इनहेरिटेंस विधि कार्यान्वयन इंटरफेस के मल्टीपल-इनहेरिटेंस के साथ भी डायमंड प्रॉब्लम को प्रदर्शित नहीं करता है। जावा 8 और सी # 8 में इंटरफेस के लिए डिफ़ॉल्ट कार्यान्वयन की शुरुआत के साथ, डायमंड प्रॉब्लम उत्पन्न करना अभी भी संभव है, हालांकि यह केवल संकलन-समय त्रुटि के रूप में दिखाई देगा।
यह भी देखें
संदर्भ
- ↑ Cargill, T. A. (Winter 1991). "Controversy: The Case Against Multiple Inheritance in C++". Computing Systems. 4 (1): 69–82.
- ↑ Waldo, Jim (Spring 1991). "Controversy: The Case For Multiple Inheritance in C++". Computing Systems. 4 (2): 157–171.
- ↑ Schärli, Nathanael; Ducasse, Stéphane; Nierstrasz, Oscar; Black, Andrew. "Traits: Composable Units of Behavior" (PDF). Web.cecs.pdx.edu. Retrieved 2016-10-21.
- ↑ "incr Tcl". blog.tcl.tk. Retrieved 2020-04-14.
- ↑ "Introduction to the Tcl Programming Language". www2.lib.uchicago.edu. Retrieved 2020-04-14.
- ↑ Martin, Robert C. (1997-03-09). "Java and C++: A critical comparison" (PDF). Objectmentor.com. Archived from the original (PDF) on 2005-10-24. Retrieved 2016-10-21.
- ↑ "Standard ECMA-367". Ecma-international.org. Retrieved 2016-10-21.
- ↑ "State of the Lambda". Cr.openjdk.java.net. Retrieved 2016-10-21.
- ↑ "perlobj". perldoc.perl.org. Retrieved 2016-10-21.
- ↑ Abstract. "The Python 2.3 Method Resolution Order". Python.org. Retrieved 2016-10-21.
- ↑ "Unifying types and classes in Python 2.2". Python.org. Retrieved 2016-10-21.
- ↑ "Manpage of class". Tcl.tk. 1999-11-16. Retrieved 2016-10-21.
- ↑ "Object Interfaces - Manual". PHP.net. 2007-07-04. Retrieved 2016-10-21.
अग्रिम पठन
- Stroustrup, Bjarne (1999). Multiple Inheritance for C++. Proceedings of the Spring 1987 European Unix Users Group Conference
- Object-Oriented Software Construction, Second Edition, by Bertrand Meyer, Prentice Hall, 1997, ISBN 0-13-629155-4
- Eddy Truyen; Wouter Joosen; Bo Nørregaard; Pierre Verbaeten (2004). "A Generalization and Solution to the Common Ancestor Dilemma Problem in Delegation-Based Object Systems" (PDF). Proceedings of the 2004 Dynamic Aspects Workshop (103–119).
- Ira R. Forman; Scott Danforth (1999). Putting Metaclasses to Work. ISBN 0-201-43305-2.