इनहेरिटेंस (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग)

From Vigyanwiki
Revision as of 03:03, 17 February 2023 by alpha>Indicwiki (Created page with "{{Short description|Process of deriving classes from, and organizing them into, a hierarchy}} {{cleanup|reason=Cluttered|date=April 2015}} वस्तु-उन्मुख...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

वस्तु-उन्मुख प्रोग्रामिंग में, वंशानुक्रम एक वस्तु (कंप्यूटर विज्ञान) या कक्षा (कंप्यूटर प्रोग्रामिंग) को किसी अन्य वस्तु (प्रोटोटाइप-आधारित प्रोग्रामिंग | प्रोटोटाइप-आधारित विरासत) या वर्ग (वर्ग-आधारित प्रोग्रामिंग | वर्ग-आधारित विरासत) पर आधारित करने का तंत्र है। ), समान कार्यान्वयन को बनाए रखना। सुपर क्लास या नाजुक आधार वर्ग जैसे मौजूदा वर्गों से नई कक्षाएं (#सबक्लास और सुपरक्लास) प्राप्त करने और फिर उन्हें कक्षाओं के पदानुक्रम में बनाने के रूप में भी परिभाषित किया गया है। अधिकांश वर्ग-आधारित वस्तु-उन्मुख भाषाओं में, वंशानुक्रम के माध्यम से बनाई गई एक वस्तु, एक बाल वस्तु, मूल वस्तु के सभी गुणों और व्यवहारों को प्राप्त करती है, अपवाद के साथ: कंस्ट्रक्टर (ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग), विध्वंसक, ऑपरेटर ओवरलोडिंग और मित्र बेस क्लास के कार्य। वंशानुक्रम प्रोग्रामर को मौजूदा कक्षाओं पर निर्मित कक्षाएं बनाने की अनुमति देता है,[1] कोड का पुन: उपयोग करने और स्वतंत्र रूप से सार्वजनिक कक्षाओं और इंटरफ़ेस (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) के माध्यम से मूल सॉफ़्टवेयर का विस्तार करने के लिए समान व्यवहार (वर्ग आरेख # बोध/कार्यान्वयन) को बनाए रखते हुए एक नया कार्यान्वयन निर्दिष्ट करने के लिए। वंशानुक्रम के माध्यम से वस्तुओं या वर्गों के संबंध एक निर्देशित अचक्रीय ग्राफ को जन्म देते हैं।

विरासत में मिली कक्षा को उसके मूल वर्ग या सुपर क्लास का उपवर्ग कहा जाता है। वर्ग-आधारित और प्रोटोटाइप-आधारित प्रोग्रामिंग दोनों के लिए वंशानुक्रम शब्द का उपयोग शिथिल रूप से किया जाता है, लेकिन संकीर्ण उपयोग में यह शब्द वर्ग-आधारित प्रोग्रामिंग के लिए आरक्षित है (एक वर्ग 'दूसरे' से प्राप्त होता है), प्रोटोटाइप-आधारित में संबंधित तकनीक के साथ प्रोग्रामिंग को इसके बजाय डेलिगेशन (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) कहा जाता है (एक ऑब्जेक्ट दूसरे को डेलीगेट करता है)। क्लास-मॉडिफाइंग इनहेरिटेंस पैटर्न को सरल नेटवर्क इंटरफ़ेस पैरामीटर के अनुसार पूर्व-परिभाषित किया जा सकता है जैसे कि अंतर-भाषा संगतता संरक्षित है।[2][3] वंशानुक्रम को उपप्रकार के साथ भ्रमित नहीं होना चाहिए।[4][5] कुछ भाषाओं में वंशानुक्रम और उपप्रकार सहमत हैं,[lower-alpha 1] जबकि अन्य में वे भिन्न हैं; सामान्य तौर पर, उप-टाइपिंग एक-एक संबंध स्थापित करता है, जबकि वंशानुक्रम केवल कार्यान्वयन का पुन: उपयोग करता है और एक वाक्य-विन्यास संबंध स्थापित करता है, जरूरी नहीं कि एक सिमेंटिक संबंध (विरासत व्यवहार उपप्रकार सुनिश्चित नहीं करता है)। इन अवधारणाओं को अलग करने के लिए, उपप्रकार को कभी-कभी इंटरफ़ेस वंशानुक्रम के रूप में संदर्भित किया जाता है (यह स्वीकार किए बिना कि प्रकार चर का विशेषज्ञता भी एक उपप्रकार संबंध को प्रेरित करता है), जबकि यहाँ परिभाषित वंशानुक्रम को कार्यान्वयन विरासत या कोड वंशानुक्रम के रूप में जाना जाता है।[6] फिर भी, वंशानुक्रम उपप्रकार संबंधों को स्थापित करने के लिए आमतौर पर इस्तेमाल किया जाने वाला तंत्र है।[7] वंशानुक्रम वस्तु संरचना के विपरीत है, जहां एक वस्तु में दूसरी वस्तु होती है (या एक वर्ग की वस्तुओं में दूसरी कक्षा की वस्तुएं होती हैं); वंशानुक्रम पर रचना देखें। उप-टाइपिंग के is-एक संबंध के विपरीत रचना एक है-एक संबंध को लागू करती है।

इतिहास

1966 में, टोनी होरे ने रिकॉर्ड्स पर कुछ टिप्पणियां प्रस्तुत कीं, और विशेष रूप से रिकॉर्ड उपवर्गों के विचार प्रस्तुत किए, सामान्य गुणों के साथ रिकॉर्ड प्रकार लेकिन एक संस्करण टैग द्वारा भेदभाव किया गया और वेरिएंट के लिए निजी क्षेत्र थे।[8] इससे प्रभावित होकर, 1967 में ओले-जोहान डाहल और क्रिस्टन न्यागार्ड ने एक ऐसा डिज़ाइन प्रस्तुत किया, जिसमें उन वस्तुओं को निर्दिष्ट करने की अनुमति दी गई जो विभिन्न वर्गों से संबंधित थीं, लेकिन उनमें सामान्य गुण थे। सामान्य गुणों को एक सुपरक्लास में एकत्र किया गया था, और प्रत्येक सुपरक्लास में संभावित रूप से एक सुपरक्लास हो सकता है। एक उपवर्ग के मान इस प्रकार मिश्रित वस्तुएँ थे, जिसमें विभिन्न सुपरक्लास से संबंधित कुछ उपसर्ग भाग शामिल थे, साथ ही उपवर्ग से संबंधित एक मुख्य भाग। ये सभी अंग आपस में जुड़े हुए थे।[9] एक यौगिक वस्तु के गुण डॉट नोटेशन द्वारा सुलभ होंगे। इस विचार को सबसे पहले Simula 67 प्रोग्रामिंग भाषा में अपनाया गया था।[10] यह विचार तब स्मॉलटाक, सी ++, जावा (प्रोग्रामिंग भाषा), पायथन (प्रोग्रामिंग भाषा), और कई अन्य भाषाओं में फैल गया।

प्रकार

एकल वंशानुक्रम
एकाधिक वंशानुक्रम

प्रतिमान और विशिष्ट भाषा के आधार पर विभिन्न प्रकार की विरासत हैं।[11]

एकल वंशानुक्रम
जहां उपवर्गों को एक सुपरक्लास की विशेषताएं विरासत में मिलती हैं। एक वर्ग दूसरे वर्ग के गुण प्राप्त करता है।

एकाधिक वंशानुक्रम

जहाँ एक वर्ग में एक से अधिक सुपरक्लास हो सकते हैं और सभी मूल वर्गों से सुविधाएँ प्राप्त कर सकते हैं।

"Multiple inheritance ... was widely supposed to be very difficult to implement efficiently. For example, in a summary of C++ in his book on Objective C, Brad Cox actually claimed that adding multiple inheritance to C++ was impossible. Thus, multiple inheritance seemed more of a challenge. Since I had considered multiple inheritance as early as 1982 and found a simple and efficient implementation technique in 1984, I couldn't resist the challenge. I suspect this to be the only case in which fashion affected the sequence of events."[12]

बहुस्तरीय वंशानुक्रम

जहां एक उपवर्ग दूसरे उपवर्ग से विरासत में मिला है। यह असामान्य नहीं है कि एक वर्ग किसी अन्य व्युत्पन्न वर्ग से प्राप्त होता है जैसा कि बहुस्तरीय विरासत में दिखाया गया है।
बहुस्तरीय विरासत
: वर्ग ए व्युत्पन्न वर्ग बी के लिए आधार वर्ग के रूप में कार्य करता है, जो बदले में व्युत्पन्न वर्ग सी के लिए आधार वर्ग के रूप में कार्य करता है। कक्षा बी को मध्यवर्ती आधार वर्ग के रूप में जाना जाता है क्योंकि यह ए और सी के बीच विरासत के लिए एक लिंक प्रदान करता है। श्रृंखला एबीसी को वंशानुक्रम पथ के रूप में जाना जाता है।
बहुस्तरीय विरासत के साथ एक व्युत्पन्न वर्ग निम्नानुसार घोषित किया गया है:
<वाक्यविन्यास लैंग = सीपीपी>

एक कक्षा { ... }; // बेस क्लास कक्षा बी: सार्वजनिक ए {...}; // बी ए से व्युत्पन्न कक्षा सी: सार्वजनिक बी {...}; // सी बी से व्युत्पन्न </वाक्यविन्यास हाइलाइट>

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

उपवर्ग और अधिवर्ग

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

व्युत्पन्न वर्ग को परिभाषित करने का सामान्य रूप है:[13] <वाक्यविन्यास लैंग = सीपीपी> वर्ग उपवर्ग: दृश्यता सुपरक्लास {

   // उपवर्ग के सदस्य

}; </वाक्यविन्यास हाइलाइट>

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

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

गैर-उपवर्गीय वर्ग

कुछ भाषाओं में एक क्लास को क्लास (कंप्यूटर प्रोग्रामिंग)#नॉन-सबक्लासेबल|नॉन-सबक्लासेबल के रूप में क्लास डिक्लेरेशन में कुछ वर्ग संशोधक्स जोड़कर घोषित किया जा सकता है। उदाहरणों में शामिल हैं final फ़ाइनल (जावा) और C++ 11 के बाद या बाद में कीवर्ड sealed सी # में कीवर्ड। इस तरह के संशोधक वर्ग घोषणा से पहले जोड़े जाते हैं class कीवर्ड और वर्ग पहचानकर्ता घोषणा। ऐसे गैर-उपवर्गीय वर्ग पुन: प्रयोज्यता को प्रतिबंधित करते हैं, खासकर जब डेवलपर्स के पास केवल पूर्वनिर्मित बाइनरी फ़ाइल तक पहुंच होती है और स्रोत कोड नहीं।

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

गैर-अतिव्यापी तरीके

जैसे कक्षाएं गैर-उपवर्गीय हो सकती हैं, विधि घोषणाओं में विधि संशोधक हो सकते हैं जो विधि को ओवरराइड होने से रोकते हैं (यानी एक ही नाम के साथ एक नए फ़ंक्शन के साथ प्रतिस्थापित किया जाता है और उपवर्ग में हस्ताक्षर टाइप करता है)। एक एनकैप्सुलेशन (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) # सूचना छिपाने की तंत्र विधि के रूप में गैर-अतिव्यापी है, क्योंकि यह कक्षा के अलावा अन्य वर्गों द्वारा सुलभ नहीं है, यह एक सदस्य कार्य है (यह सी ++ के लिए सच नहीं है, हालांकि)। ए final जावा में विधि, ए sealed सी # या ए में विधि frozen एफिल में फीचर को ओवरराइड नहीं किया जा सकता है।

आभासी तरीके

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

विरासत में मिले सदस्यों की दृश्यता

निम्न तालिका से पता चलता है कि सी ++ द्वारा स्थापित शब्दावली का उपयोग करते हुए, वर्ग को प्राप्त करते समय दी गई दृश्यता पर कौन से चर और कार्य विरासत में मिलते हैं।[14]

Base class visibility Derived class visibility
Private derivation Protected derivation Public derivation
  • Private →
  • Protected →
  • Public →
  • Not inherited
  • Private
  • Private
  • Not inherited
  • Protected
  • Protected
  • Not inherited
  • Protected
  • Public


अनुप्रयोग

वंशानुक्रम का उपयोग दो या दो से अधिक वर्गों को एक दूसरे से सह-संबंधित करने के लिए किया जाता है।


ओवरराइडिंग

विधि ओवरराइडिंग का चित्रण

वस्तु-उन्मुख प्रोग्रामिंग भाषाओं की सूची सूची | ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग लैंग्वेज एक क्लास या ऑब्जेक्ट को एक पहलू के कार्यान्वयन को बदलने की अनुमति देती हैं - आमतौर पर एक व्यवहार - जो इसे विरासत में मिला है। इस प्रक्रिया को ओवरराइडिंग विधि कहा जाता है। ओवरराइडिंग एक जटिलता का परिचय देती है: व्यवहार का कौन सा संस्करण विरासत में मिले वर्ग का उपयोग करता है - वह जो अपनी कक्षा का हिस्सा है, या माता-पिता (आधार) वर्ग से एक है? उत्तर प्रोग्रामिंग भाषाओं के बीच भिन्न होता है, और कुछ भाषाएं यह इंगित करने की क्षमता प्रदान करती हैं कि एक विशेष व्यवहार को ओवरराइड नहीं किया जाना चाहिए और बेस क्लास द्वारा परिभाषित व्यवहार करना चाहिए। उदाहरण के लिए, सी # में, आधार विधि या संपत्ति को उप-वर्ग में केवल ओवरराइड किया जा सकता है यदि इसे वर्चुअल, सार, या ओवरराइड संशोधक के साथ चिह्नित किया गया हो, जबकि प्रोग्रामिंग भाषाओं जैसे जावा में, अन्य विधियों को ओवरराइड करने के लिए विभिन्न विधियों को बुलाया जा सकता है।[15] ओवरराइडिंग का एक विकल्प विरासत में मिले कोड को छिपाना (प्रोग्रामिंग) करना है।

कोड पुन: उपयोग

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

निम्नलिखित पायथन उदाहरण में, उपवर्ग SquareSumComputer और CubeSumComputer ओवरराइड करें transform() आधार वर्ग की विधि SumComputer. बेस क्लास में दो पूर्णांकों के बीच वर्ग संख्या के योग की गणना करने के लिए ऑपरेशन शामिल हैं। उपवर्ग बेस क्लास की सभी कार्यक्षमताओं का पुन: उपयोग करता है, ऑपरेशन के अपवाद के साथ जो किसी संख्या को उसके वर्ग में बदल देता है, इसे एक ऐसे ऑपरेशन से बदल देता है जो एक संख्या को उसके वर्ग संख्या और घन संख्या में क्रमशः बदल देता है। उपवर्ग इसलिए दो पूर्णांकों के बीच वर्गों/घनों के योग की गणना करते हैं।

नीचे पायथन का एक उदाहरण है। <वाक्यविन्यास लैंग = अजगर> क्लास समकंप्यूटर:

   def __init__(self, a, b):
       स्व। ए = ए
       स्वयं बी = बी
   डीईएफ़ परिवर्तन (स्वयं, एक्स):
       लागू नहीं किया त्रुटि बढ़ाएँ
   डेफ इनपुट (स्वयं):
       रिटर्न रेंज (self.a, self.b)
   डीईएफ़ गणना (स्वयं):
       वापसी योग (self.transform (मान) self.inputs में मूल्य के लिए))

क्लास स्क्वायरसम कंप्यूटर (सम कंप्यूटर):

   डीईएफ़ परिवर्तन (स्वयं, एक्स):
       रिटर्न एक्स * एक्स

क्लास क्यूबसमकंप्यूटर(SumComputer):

   डीईएफ़ परिवर्तन (स्वयं, एक्स):
       रिटर्न एक्स * एक्स * एक्स

</वाक्यविन्यास हाइलाइट>

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


वंशानुक्रम बनाम उपप्रकार

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

<वाक्यविन्यास लैंग = सीपीपी> एक कक्षा {

जनता:
 शून्य DoSomethingAlike () स्थिरांक {}

};

कक्षा बी: सार्वजनिक ए {

जनता:
 शून्य करो कुछ ऐसा करो () स्थिरांक {}

};

शून्य यूज़एएनए (स्थिरांक ए और ए) {

 ए.डू समथिंगएलाइक ();

}

शून्य कुछ फंक () {

 बी बी;
 यूज़एएनए (बी); // बी को ए के लिए प्रतिस्थापित किया जा सकता है।

} </वाक्यविन्यास हाइलाइट>

प्रोग्रामिंग भाषाओं में जो एक उपप्रकार बहुरूपता के रूप में वंशानुक्रम का समर्थन नहीं करते हैं, डेटा प्रकार के बीच संबंध की तुलना में आधार वर्ग और व्युत्पन्न वर्ग के बीच संबंध केवल कार्यान्वयन (कोड पुन: उपयोग के लिए एक तंत्र) के बीच संबंध है। वंशानुक्रम, यहां तक ​​कि प्रोग्रामिंग भाषाओं में भी जो एक उपप्रकार तंत्र के रूप में वंशानुक्रम का समर्थन करते हैं, आवश्यक रूप से व्यवहारिक उपप्रकार की आवश्यकता नहीं है। एक वर्ग को प्राप्त करना पूरी तरह से संभव है जिसका ऑब्जेक्ट गलत तरीके से व्यवहार करेगा जब उस संदर्भ में उपयोग किया जाता है जहां मूल वर्ग की अपेक्षा की जाती है; लिस्कोव प्रतिस्थापन सिद्धांत देखें। [18] (संकेत (लाक्षणिकता) की तुलना करें। अर्थ/निरूपण।) कुछ ओओपी भाषाओं में, कोड पुन: उपयोग और उपप्रकार की धारणा मेल खाती है क्योंकि एक उपप्रकार घोषित करने का एकमात्र तरीका एक नए वर्ग को परिभाषित करना है जो दूसरे के कार्यान्वयन को प्राप्त करता है।

डिजाइन की कमी

एक कार्यक्रम को डिजाइन करने में विरासत का बड़े पैमाने पर उपयोग कुछ बाधाओं को लागू करता है।

उदाहरण के लिए, एक वर्ग पर विचार करें Person जिसमें व्यक्ति का नाम, जन्म तिथि, पता और फोन नंबर होता है। हम एक उपवर्ग को परिभाषित कर सकते हैं Person बुलाया Student जिसमें व्यक्ति का ग्रेड बिंदु औसत और ली गई कक्षाएं, और का एक अन्य उपवर्ग शामिल है Person बुलाया Employee जिसमें व्यक्ति का पद-शीर्षक, नियोक्ता और वेतन शामिल होता है।

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

Singleness
सिंगल इनहेरिटेंस का उपयोग करके, एक सबक्लास केवल एक सुपरक्लास से इनहेरिट कर सकता है। ऊपर दिए गए उदाहरण को जारी रखते हुए, a Person वस्तु या तो एक हो सकती है Student या एक Employee, लेकिन दोनों नहीं। एकाधिक वंशानुक्रम का उपयोग आंशिक रूप से इस समस्या को हल करता है, जैसा कि तब परिभाषित किया जा सकता है StudentEmployee वर्ग जो दोनों से विरासत में मिला है Student और Employee. हालांकि, अधिकांश कार्यान्वयनों में, यह अभी भी प्रत्येक सुपरक्लास से केवल एक बार इनहेरिट कर सकता है, और इस प्रकार, उन मामलों का समर्थन नहीं करता है जिनमें एक छात्र के पास दो नौकरियां हैं या दो संस्थानों में भाग लेता है। एफिल में उपलब्ध वंशानुक्रम मॉडल हीरा समस्या के समर्थन के माध्यम से इसे संभव बनाता है।

स्थिर: किसी वस्तु का वंशानुक्रम पदानुक्रम उदाहरण (कंप्यूटर विज्ञान) पर तय होता है जब वस्तु का प्रकार चुना जाता है और समय के साथ नहीं बदलता है। उदाहरण के लिए, वंशानुक्रम ग्राफ a की अनुमति नहीं देता है Student बनने की वस्तु Employee इसकी स्थिति को बनाए रखते हुए वस्तु Person superclass. (इस तरह का व्यवहार, हालांकि, डेकोरेटर पैटर्न के साथ प्राप्त किया जा सकता है।) कुछ ने वंशानुक्रम की आलोचना की है, यह तर्क देते हुए कि यह डेवलपर्स को उनके मूल डिजाइन मानकों में बंद कर देता है।[19] दृश्यता: जब भी क्लाइंट कोड की किसी ऑब्जेक्ट तक पहुंच होती है, तो आमतौर पर ऑब्जेक्ट के सभी सुपरक्लास डेटा तक उसकी पहुंच होती है। यहां तक ​​​​कि अगर सुपरक्लास को सार्वजनिक घोषित नहीं किया गया है, तो क्लाइंट अभी भी टाइपकास्ट (प्रोग्रामिंग) ऑब्जेक्ट को अपने सुपरक्लास प्रकार में कर सकता है। उदाहरण के लिए, फ़ंक्शन को पॉइंटर देने का कोई तरीका नहीं है Studentका ग्रेड पॉइंट औसत और ट्रांसक्रिप्ट भी उस फ़ंक्शन को छात्र में संग्रहीत सभी व्यक्तिगत डेटा तक पहुंच प्रदान किए बिना Person superclass. सी ++ और जावा सहित कई आधुनिक भाषाएं, एक संरक्षित एक्सेस संशोधक प्रदान करती हैं जो उपवर्गों को डेटा तक पहुंचने की अनुमति देता है, बिना किसी कोड को इनहेरिटेंस की श्रृंखला के इसे एक्सेस करने की अनुमति देता है।

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

मुद्दे और विकल्प

कार्यान्वयन वंशानुक्रम कम से कम 1990 के दशक से प्रोग्रामरों और भूमिका उन्मुख प्रोग्रामिंग के सिद्धांतकारों के बीच विवादास्पद रहा है। उनमें से डिजाइन पैटर्न्स के लेखक हैं, जो इसके बजाय इंटरफ़ेस इनहेरिटेंस की वकालत करते हैं, और इनहेरिटेंस पर रचना का पक्ष लेते हैं। उदाहरण के लिए, कक्षाओं के बीच विरासत की स्थिर प्रकृति को दूर करने के लिए डेकोरेटर पैटर्न (जैसा कि #Design बाधाओं का उल्लेख किया गया है) प्रस्तावित किया गया है। एक ही समस्या के अधिक मौलिक समाधान के रूप में, भूमिका-उन्मुख प्रोग्रामिंग एक नई अवधारणा में वंशानुक्रम और संरचना के गुणों को जोड़कर, एक विशिष्ट संबंध का परिचय देती है।[citation needed] एलन होलूब के अनुसार, इम्प्लीमेंटेशन इनहेरिटेंस के साथ मुख्य समस्या यह है कि यह फ्रैजाइल बेस क्लास के रूप में अनावश्यक कपलिंग (कंप्यूटर प्रोग्रामिंग) का परिचय देता है। नाजुक आधार वर्ग समस्या:[6] बेस क्लास के कार्यान्वयन में संशोधन उपवर्गों में अनजाने व्यवहार परिवर्तन का कारण बन सकता है। इंटरफेस का उपयोग इस समस्या से बचा जाता है क्योंकि कोई कार्यान्वयन साझा नहीं किया जाता है, केवल एपीआई।[19] इसे बताने का एक और तरीका यह है कि वंशानुक्रम एनकैप्सुलेशन (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) को तोड़ता है।[20] समस्या खुले ऑब्जेक्ट-ओरिएंटेड सिस्टम जैसे सॉफ्टवेयर ढांचा में स्पष्ट रूप से सामने आती है, जहाँ क्लाइंट कोड को सिस्टम-आपूर्ति वाली कक्षाओं से विरासत में मिलने की उम्मीद की जाती है और फिर इसके एल्गोरिदम में सिस्टम की कक्षाओं के लिए प्रतिस्थापित किया जाता है।[6] कथित तौर पर, जावा के आविष्कारक जेम्स गोस्लिंग ने कार्यान्वयन विरासत के खिलाफ बात की है, यह कहते हुए कि यदि वह जावा को फिर से डिज़ाइन करना चाहते हैं तो वह इसे शामिल नहीं करेंगे।[19] भाषा डिजाइन जो उपप्रकार (इंटरफ़ेस वंशानुक्रम) से वंशानुक्रम को कम करते हैं, 1990 की शुरुआत में दिखाई दिए;[21] इसका एक आधुनिक उदाहरण गो (प्रोग्रामिंग भाषा) प्रोग्रामिंग भाषा है।

जटिल वंशानुक्रम, या अपर्याप्त रूप से परिपक्व डिजाइन के भीतर उपयोग की जाने वाली विरासत, यो-यो समस्या का कारण बन सकती है। 1990 के दशक के अंत में जब वंशानुक्रम का उपयोग संरचना कार्यक्रमों के प्राथमिक दृष्टिकोण के रूप में किया गया था, तो डेवलपर्स ने कोड को वंशानुक्रम की अधिक परतों में तोड़ने का प्रयास किया क्योंकि सिस्टम की कार्यक्षमता बढ़ गई थी। यदि एक विकास दल ने एकल जिम्मेदारी सिद्धांत के साथ वंशानुक्रम की कई परतों को संयोजित किया, तो इसके परिणामस्वरूप कोड की बहुत पतली परतें बन गईं, जिसमें वास्तविक कोड की केवल 1 या 2 पंक्तियों वाली कई परतें थीं।[citation needed] बहुत सी परतें डिबगिंग को एक महत्वपूर्ण चुनौती बनाती हैं, क्योंकि यह निर्धारित करना कठिन हो जाता है कि किस परत को डीबग करने की आवश्यकता है।

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

यह भी देखें


टिप्पणियाँ

  1. This is generally true only in statically-typed class-based OO languages, such as C++, C#, Java, and Scala.


संदर्भ

  1. Johnson, Ralph (August 26, 1991). "Designing Reusable Classes" (PDF). www.cse.msu.edu.
  2. Madsen, OL (1989). "Virtual classes: A powerful mechanism in object-oriented programming". Conference proceedings on Object-oriented programming systems, languages and applications.
  3. Davies, Turk (2021). Advanced Methods and Deep Learning in Computer Vision. Elsevier Science. pp. 179–342.
  4. 4.0 4.1 Cook, William R.; Hill, Walter; Canning, Peter S. (1990). Inheritance is not subtyping. Proceedings of the 17th ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages (POPL). pp. 125–135. CiteSeerX 10.1.1.102.8635. doi:10.1145/96709.96721. ISBN 0-89791-343-4.
  5. Cardelli, Luca (1993). Typeful Programming (Technical report). Digital Equipment Corporation. p. 32–33. SRC Research Report 45.
  6. 6.0 6.1 6.2 Mikhajlov, Leonid; Sekerinski, Emil (1998). A study of the fragile base class problem (PDF). Proceedings of the 12th European Conference on Object-Oriented Programming (ECOOP). Lecture Notes in Computer Science. Vol. 1445. Springer. pp. 355–382. doi:10.1007/BFb0054099. ISBN 978-3-540-64737-9. Archived from the original (PDF) on 2017-08-13. Retrieved 2015-08-28.
  7. Tempero, Ewan; Yang, Hong Yul; Noble, James (2013). What programmers do with inheritance in Java (PDF). ECOOP 2013–Object-Oriented Programming. Lecture Notes in Computer Science. Vol. 7920. Springer. pp. 577–601. doi:10.1007/978-3-642-39038-8_24. ISBN 978-3-642-39038-8.
  8. Hoare, C. A. R. (1966). Record Handling (PDF) (Technical report). pp. 15–16.
  9. Dahl, Ole-Johan; Nygaard, Kristen (May 1967). Class and subclass declarations (PDF). IFIP Working Conference on Simulation Languages. Oslo: Norwegian Computing Center.
  10. Dahl, Ole-Johan (2004). "The Birth of Object Orientation: the Simula Languages" (PDF). From Object-Orientation to Formal Methods. 2635: 15–25. doi:10.1007/978-3-540-39993-3_3.
  11. "C++ Inheritance". www.cs.nmsu.edu.
  12. Stroustrup, Bjarne (1994). The Design and Evolution of C++. Pearson. p. 417. ISBN 9780135229477.
  13. Schildt, Herbert (2003). The complete reference C++. Tata McGraw Hill. p. 417. ISBN 978-0-07-053246-5.
  14. Balagurusamy, E. (2010). Object Oriented Programming With C++. Tata McGraw Hill. p. 213. ISBN 978-0-07-066907-9.
  15. override(C# Reference)
  16. "GotW #60: Exception-Safe Class Design, Part 2: Inheritance". Gotw.ca. Retrieved 2012-08-15.
  17. Venugopal, K.R.; Buyya, Rajkumar (2013). Mastering C++. Tata McGraw Hill Education Private Limited. p. 609. ISBN 9781259029943.
  18. Mitchell, John (2002). "10 "Concepts in object-oriented languages"". Concepts in programming language. Cambridge University Press. p. 287. ISBN 978-0-521-78098-8.
  19. 19.0 19.1 19.2 Holub, Allen (1 August 2003). "Why extends is evil". Retrieved 10 March 2015.
  20. Seiter, Linda M.; Palsberg, Jens; Lieberherr, Karl J. (1996). "Evolution of object behavior using context relations". ACM SIGSOFT Software Engineering Notes. 21 (6): 46. CiteSeerX 10.1.1.36.5053. doi:10.1145/250707.239108.
  21. America, Pierre (1991). Designing an object-oriented programming language with behavioural subtyping. REX School/Workshop on the Foundations of Object-Oriented Languages. Lecture Notes in Computer Science. Vol. 489. pp. 60–90. doi:10.1007/BFb0019440. ISBN 978-3-540-53931-5.


अग्रिम पठन