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

From Vigyanwiki
Revision as of 13:34, 18 February 2023 by alpha>Radhamishra

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

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

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

अधिवर्ग के अतिरिक्त अन्य वैकल्पिक समाधान एक इंटरफेस (वस्तु-उन्मुख प्रोग्राम) हो सकता है।

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


जावा उदाहरण

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

class Super {

 private int counter = 0;

 void inc1() {
    counter++;
 }

 void inc2() {
    counter++;
 }

}

class Sub extends Super {

 @Override
 void inc2() {
    inc1();
 }

}


उप के एक उदाहरण पर गतिशील रूप से बाध्य विधि inc2() को निर्देशित करने से क्षेत्र काउंटर को एक से सही रूप से बढ़ाया जाएगा। यदि हालांकि अधिवर्ग का कोड निम्नलिखित तरीके से परिवर्तित कर दिया गया है:

class Super {

 private int counter = 0;

 void inc1() {
    inc2();
 }

 void inc2() {
    counter++;
 }
}


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

समाधान

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

यह भी देखें

संदर्भ

  1. "Selective Open Recursion: A Solution to the Fragile Base Class Problem", Jonathan Aldrich
  2. "Selective Open Recursion: A Solution to the Fragile Base Class Problem", Lambda the Ultimate
  3. "Override modifier - C# Reference".


बाहरी संबंध