नाजुक आधार वर्ग

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

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

सुपरक्लास के बजाय एक अन्य वैकल्पिक समाधान एक इंटरफ़ेस (ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग) हो सकता है।

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

जावा उदाहरण
निम्नलिखित तुच्छ उदाहरण जावा प्रोग्रामिंग भाषा में लिखा गया है और दिखाता है कि कैसे एक बेस क्लास का प्रतीत होता है कि सुरक्षित संशोधन एक इनहेरिटिंग सबक्लास को एक अनंत रिकर्सन में प्रवेश करके खराबी का कारण बन सकता है जिसके परिणामस्वरूप स्टैक ओवरफ्लो होगा। <वाक्यविन्यास प्रकाश लैंग = जावा> क्लास सुपर {

निजी इंट काउंटर = 0;

शून्य inc1 { काउंटर ++; }

शून्य inc2 { काउंटर ++; }

}

वर्ग उप का विस्तार सुपर {

@Override शून्य inc2 { inc1 ; }

} 

उप के एक उदाहरण पर गतिशील रूप से बाध्य विधि inc2 को कॉल करने से फ़ील्ड काउंटर को एक से सही ढंग से बढ़ाया जाएगा। अगर हालांकि सुपरक्लास का कोड निम्न तरीके से बदल दिया गया है: <वाक्यविन्यास प्रकाश लैंग = जावा> क्लास सुपर {

निजी इंट काउंटर = 0;

शून्य inc1 { inc2 ; }

शून्य inc2 { काउंटर ++; } } 

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

समाधान

 * उद्देश्य सी में ऑब्जेक्टिव-सी # कैटेगरी के साथ-साथ ऑब्जेक्टिव-सी # नॉन-फ्रैजाइल इंस्टेंस वेरिएबल्स | नॉन-फ्रैजाइल इंस्टेंस वेरिएबल्स हैं।
 * घटक पास्कल सुपरक्लास (कंप्यूटर विज्ञान) को बहिष्कृत करता है।
 * जावा (प्रोग्रामिंग भाषा), C++ (C++11 के बाद से) और D (प्रोग्रामिंग लैंग्वेज) इनहेरिटेंस या क्लास मेथड को ओवरराइड करने की अनुमति देते हैं, जो कि कीवर्ड के साथ क्रमशः एक क्लास या मेथड की घोषणा को लेबल करके प्रतिबंधित किया जाता है। . प्रभावी जावा पुस्तक में, लेखक जोशुआ बलोच लिखते हैं (आइटम 17 में) कि प्रोग्रामर को विरासत के लिए डिजाइन और दस्तावेज करना चाहिए या अन्यथा इसे प्रतिबंधित करना चाहिए।
 * C Sharp (प्रोग्रामिंग लैंग्वेज)|C# और VB.NET जैसे Java होते हैं और वर्ग घोषणा कीवर्ड वंशानुक्रम को प्रतिबंधित करने के लिए, और कीवर्ड का उपयोग करने के लिए एक उपवर्ग की आवश्यकता होती है ओवरराइडिंग विधियों पर, वही समाधान बाद में स्काला द्वारा अपनाया गया।
 * Scala (प्रोग्रामिंग लैंग्वेज) को कीवर्ड का उपयोग करने के लिए एक उपवर्ग की आवश्यकता होती है माता-पिता वर्ग विधि को ओवरराइड करने के लिए स्पष्ट रूप से। स्कैला में प्रोग्रामिंग, द्वितीय संस्करण पुस्तक में, लेखक लिखता है कि (यहां संशोधनों के साथ) यदि कोई विधि f नहीं थी, तो क्लाइंट के विधि f के मूल कार्यान्वयन में ओवरराइड संशोधक नहीं हो सकता था। एक बार जब आप अपने पुस्तकालय वर्ग के दूसरे संस्करण में f विधि जोड़ लेते हैं, तो क्लाइंट कोड का एक पुन: संकलन गलत व्यवहार के बजाय एक संकलन त्रुटि देगा।
 * कोटलिन (प्रोग्रामिंग भाषा) में कक्षाएं और विधियाँ डिफ़ॉल्ट रूप से अंतिम होती हैं। वर्ग वंशानुक्रम को सक्षम करने के लिए, वर्ग को इसके साथ चिह्नित किया जाना चाहिए  संशोधक। इसी तरह, एक विधि के रूप में चिह्नित किया जाना चाहिए   विधि को ओवरराइड करने की अनुमति देने के लिए।
 * जूलिया (प्रोग्रामिंग लैंग्वेज) अमूर्त प्रकारों के केवल उपप्रकार की अनुमति देता है और वंशानुक्रम (वस्तु-उन्मुख प्रोग्रामिंग) के विकल्प के रूप में रचना का उपयोग करता है। हालाँकि इसमें कई प्रेषण हैं।

यह भी देखें

 * नाजुक बाइनरी इंटरफ़ेस समस्या
 * कार्यान्वयन विरासत
 * वंशानुक्रम शब्दार्थ
 * सॉफ्टवेयर भंगुरता
 * आभासी विरासत