एकाधिक वंशानुक्रम
एकाधिक वंशानुक्रम कुछ ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग भाषा की ऐसी विशेषता है जिसमें ऑब्जेक्ट या क्लास (कंप्यूटर प्रोग्रामिंग) एक से अधिक पैरेंट ऑब्जेक्ट या सुपरक्लास (कंप्यूटर साइंस) से वंशानुक्रम (वस्तु-उन्मुख प्रोग्रामिंग) कर सकता है। यह एकल वंशानुक्रम से भिन्न है, जहाँ एक वस्तु या वर्ग केवल एक विशेष वस्तु या वर्ग से प्राप्त हो सकता है।
एकाधिक वंशानुक्रम कई वर्षों से विवादास्पद मुद्दा रहा है,[1][2] विरोधियों के साथ हीरे की समस्या जैसी स्थितियों में इसकी बढ़ी हुई जटिलता और अस्पष्टता की ओर इशारा करते हुए, जहां यह अस्पष्ट हो सकता है कि किस मूल वर्ग से विशेष विशेषता विरासत में मिली है यदि एक से अधिक मूल वर्ग उक्त विशेषता को लागू करते हैं। वर्चुअल विरासत का उपयोग करने सहित इसे विभिन्न तरीकों से संबोधित किया जा सकता है।[3] अस्पष्टता को संबोधित करने के लिए ऑब्जेक्ट संरचना के वैकल्पिक तरीकों जैसे मिश्रण और विशेषता (कंप्यूटर प्रोग्रामिंग) पर आधारित नहीं है,को भी प्रस्तावित किया गया है।
विवरण
ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग (OOP) में, वंशानुक्रम दो वर्गों के बीच एक संबंध का वर्णन करता है जिसमें (चाइल्ड क्लास)वर्ग, पैरेंट क्लास को उपवर्गित करता है। बच्चा माता-पिता की विधियों और विशेषताओं को विरासत में प्राप्त करता है, जिससे साझा कार्यक्षमता की अनुमति मिलती है। उदाहरण के लिए, कोई चर वर्ग स्तनपायी बना सकता है जिसमें खाने, प्रजनन, आदि जैसी विशेषताएं हों; फिर एक चाइल्ड क्लास कैट को परिभाषित करें जो चूहों का पीछा करने जैसी नई सुविधाओं को जोड़ते हुए उन विशेषताओं को स्पष्ट रूप से प्रोग्राम किए बिना इनहेरिट करती है।
एकाधिक वंशानुक्रम प्रोग्रामर्स को साथ एक से अधिक पूरी तरह से ऑर्थोगोनल पदानुक्रम का उपयोग करने की अनुमति देता है, जैसे कि कैट को कार्टून चरित्र और पालतू और स्तनपायी से इनहेरिट करने की अनुमति देना और उन सभी वर्गों के भीतर सुविधाओं तक पहुंच बनाना।
कार्यान्वयन
एकाधिक वंशानुक्रम का समर्थन करने वाली भाषाओं में शामिल हैं: C++, सामान्य लिस्प (कॉमन लिस्प ऑब्जेक्ट सिस्टम (CLOS) के माध्यम से), EuLisp (EuLisp ऑब्जेक्ट सिस्टम TELOS के माध्यम से), कर्ल (प्रोग्रामिंग भाषा), डायलन (प्रोग्रामिंग भाषा), एफिल (प्रोग्रामिंग लैंग्वेज), लोगटॉक, ऑब्जेक्ट REXX, स्काला (प्रोग्रामिंग भाषा) (मिक्सिन क्लासेस के उपयोग के माध्यम से), OCaml, पर्ल, POP-11, पायथन (प्रोग्रामिंग लैंग्वेज), R (प्रोग्रामिंग लैंग्वेज), राकू (प्रोग्रामिंग भाषा), और Tcl (बिल्ट-इन) 8.6 से या पिछले संस्करणों में इंक्रीमेंटल Tcl (Incr Tcl) के माध्यम से[4][5]).
आईबीएम सिस्टम ऑब्जेक्ट मॉडल (एसओएम) रनटाइम एकाधिक वंशानुक्रम का समर्थन करता है, और एसओएम को लक्षित करने वाली कोई भी प्रोग्रामिंग भाषा कई आधारों से विरासत में मिली नई एसओएम कक्षाओं को लागू कर सकती है।
कुछ ऑब्जेक्ट-ओरिएंटेड लैंग्वेज, जैसे कि स्विफ्ट (प्रोग्रामिंग भाषा), जावा (प्रोग्रामिंग भाषा), फोरट्रान फॉर फोरट्रान # फोरट्रान_2003, सी शार्प (प्रोग्रामिंग लैंग्वेज) | सी #, और रूबी (प्रोग्रामिंग भाषा) सिंगल इनहेरिटेंस को लागू करती हैं, हालांकि प्रोटोकॉल (ऑब्जेक्ट- उन्मुख प्रोग्रामिंग), या इंटरफेस, सच्चे एकाधिक विरासत की कुछ कार्यक्षमता प्रदान करते हैं।
PHP विशिष्ट विधि कार्यान्वयनों को इनहेरिट करने के लिए विशेषता वर्गों का उपयोग करती है। रूबी (प्रोग्रामिंग लैंग्वेज) कई तरीकों को इनहेरिट करने के लिए मॉड्यूलर प्रोग्रामिंग का उपयोग करती है।
हीरे की समस्या
हीरे की समस्या (कभी-कभी मौत का घातक हीरा कहा जाता है[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
प्रत्येक गैर-वर्चुअल इनहेरिटेंस पथ के लिएA
. C ++ को स्पष्ट रूप से यह बताने की आवश्यकता है कि किस मूल वर्ग का उपयोग किया जाना है, अर्थात।Worker::Human.Age
. सी ++ स्पष्ट दोहराया विरासत का समर्थन नहीं करता है क्योंकि सुपरक्लास का उपयोग करने के लिए अर्हता प्राप्त करने का कोई तरीका नहीं होगा (यानी कक्षा एक से अधिक बार एक व्युत्पन्न सूची में दिखाई देती है [वर्ग कुत्ता: सार्वजनिक पशु, पशु])। C++ वर्चुअल इनहेरिटेंस मैकेनिज्म के माध्यम से मल्टीपल क्लास के सिंगल इंस्टेंस को भी बनाने की अनुमति देता है (यानी।Worker::Human
औरMusician::Human
उसी वस्तु का संदर्भ देगा)। - कॉमन लिस्प कॉमन लिस्प ऑब्जेक्ट सिस्टम उचित डिफ़ॉल्ट व्यवहार और इसे ओवरराइड करने की क्षमता दोनों प्रदान करने का प्रयास करता है। डिफ़ॉल्ट रूप से, इसे सीधे शब्दों में कहें तो विधियों को क्रमबद्ध किया जाता है
D,B,C,A
, जब B को क्लास की परिभाषा में C से पहले लिखा जाता है। सबसे विशिष्ट तर्क वर्गों वाली विधि को चुना गया है (D>(B,C)>A); फिर उस क्रम में जिसमें उपवर्ग परिभाषा (बी> सी) में मूल वर्गों का नाम दिया गया है। हालाँकि, प्रोग्रामर एक विशिष्ट विधि रिज़ॉल्यूशन ऑर्डर देकर या विधियों के संयोजन के लिए एक नियम बताकर इसे ओवरराइड कर सकता है। इसे मेथड कॉम्बिनेशन कहा जाता है, जिसे पूरी तरह से नियंत्रित किया जा सकता है। MOP (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 रैखिककरण (या मेथड रेज़ोल्यूशन ऑर्डर (MRO)) एल्गोरिथम का उपयोग करके कक्षाओं की एक सूची बनाता है। वह एल्गोरिथ्म दो बाधाओं को लागू करता है: बच्चे अपने माता-पिता से पहले और यदि एक वर्ग कई वर्गों से विरासत में मिलता है, तो उन्हें आधार वर्गों के टपल में निर्दिष्ट क्रम में रखा जाता है (हालांकि इस मामले में, वंशानुक्रम ग्राफ में उच्च कुछ वर्ग निम्न वर्गों से पहले हो सकते हैं) लेखाचित्र[10]). इस प्रकार, विधि संकल्प क्रम है:D
,B
,C
,A
.[11] - रूबी (प्रोग्रामिंग लैंग्वेज) कक्षाओं में वास्तव में एक माता-पिता होते हैं, लेकिन कई मॉड्यूल से भी प्राप्त हो सकते हैं; माणिक वर्ग की परिभाषाओं को निष्पादित किया जाता है, और एक विधि की (पुनः) परिभाषा निष्पादन के समय पहले से मौजूद किसी भी परिभाषा को अस्पष्ट करती है। रनटाइम मेटाप्रोग्रामिंग की अनुपस्थिति में इसमें लगभग वही शब्दार्थ है जो सबसे सही गहराई के पहले रिज़ॉल्यूशन के रूप में है।
- स्काला (प्रोग्रामिंग लैंग्वेज) लक्षणों के कई तात्कालिकता की अनुमति देता है, जो वर्ग पदानुक्रम और विशेषता पदानुक्रम के बीच एक अंतर जोड़कर कई वंशानुक्रम की अनुमति देता है। एक वर्ग केवल एक वर्ग से उत्तराधिकारी हो सकता है, लेकिन वांछित के रूप में कई लक्षणों को मिश्रित कर सकता है। स्कैला परिणामी सूची में प्रत्येक मॉड्यूल की अंतिम घटना को छोड़कर सभी को समाप्त करने से पहले विस्तारित 'लक्षणों' की राइट-फर्स्ट डेप्थ-फर्स्ट सर्च का उपयोग करके विधि नामों को हल करता है। तो, संकल्प आदेश है: [
D
,C
,A
,B
,A
], जो कम हो जाता है [D
,C
,B
,A
]। - टीसीएल कई मूल वर्गों की अनुमति देता है; वर्ग घोषणा में विनिर्देशन का क्रम C3 रैखिककरण एल्गोरिथम का उपयोग करने वाले सदस्यों के लिए नाम रिज़ॉल्यूशन को प्रभावित करता है।[12]
ऐसी भाषाएँ जो केवल एकल वंशानुक्रम की अनुमति देती हैं, जहाँ एक वर्ग केवल एक आधार वर्ग से प्राप्त हो सकता है, हीरे की समस्या नहीं है। इसका कारण यह है कि ऐसी भाषाओं में विधियों की पुनरावृत्ति या प्लेसमेंट की परवाह किए बिना वंशानुक्रम श्रृंखला में किसी भी स्तर पर किसी भी विधि का अधिकतम एक कार्यान्वयन होता है। आमतौर पर ये भाषाएँ कक्षाओं को जावा में इंटरफ़ेस (जावा) कहे जाने वाले कई प्रोटोकॉल (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) को लागू करने की अनुमति देती हैं। ये प्रोटोकॉल विधियों को परिभाषित करते हैं लेकिन ठोस कार्यान्वयन प्रदान नहीं करते हैं। इस रणनीति का उपयोग ActionScript, C Sharp (प्रोग्रामिंग लैंग्वेज) | C#, D (प्रोग्रामिंग लैंग्वेज), Java (प्रोग्रामिंग लैंग्वेज), नेमर्ले, वस्तु पास्कल, उद्देश्य सी, स्मॉलटॉक, स्विफ्ट (प्रोग्रामिंग लैंग्वेज) और PHP (प्रोग्रामिंग लैंग्वेज) द्वारा किया गया है। ).[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.