नाजुक आधार वर्ग: Difference between revisions

From Vigyanwiki
No edit summary
No edit summary
Line 1: Line 1:
''यह लेख स्थापत्य दोष से सम्बंधित है। भाषा कार्यान्वयन समस्या के लिए दुर्बल बाइनरी इंटरफेस समस्या देखें।''{{Short description|Object-oriented programming system problem}}
''यह लेख स्थापत्य दोष से सम्बंधित है। भाषा कार्यान्वयन समस्या के लिए दुर्बल बाइनरी इंटरफेस समस्या देखें।''{{Short description|Object-oriented programming system problem}}
'''''दुर्बल आधार वर्ग''''' की समस्या वस्तु-उन्मुख प्रोग्राम प्रणाली की एक मूलभूत स्थापत्य समस्या है जहां आधार वर्ग ([[सुपरक्लास (कंप्यूटर विज्ञान)|अधिवर्ग (कंप्यूटर विज्ञान)]]) को दुर्बल माना जाता है क्योंकि [[उपवर्ग (कंप्यूटर विज्ञान)]] द्वारा निहित होने पर आधार वर्ग के लिए सुरक्षित रूप से सुरक्षित संशोधन, व्युत्पन्न वर्गों को अपक्रिया का कारण बन सकता है। प्रोग्रामर यह निर्धारित नहीं कर सकता है कि आधार वर्ग के तरीकों को वियोजन में जांच कर आधार वर्ग परिवर्तन सुरक्षित है या नहीं।
'''''दुर्बल आधार कक्षा''''' की समस्या वस्तु-उन्मुख प्रोग्राम प्रणाली की एक मूलभूत स्थापत्य समस्या है जहां आधार कक्षा ([[सुपरक्लास (कंप्यूटर विज्ञान)]]) को दुर्बल माना जाता है क्योंकि [[उपवर्ग (कंप्यूटर विज्ञान)|उप-कक्षा (कंप्यूटर विज्ञान)]] द्वारा इनहेरिटेंस होने पर आधार कक्षा के लिए सुरक्षित रूप से सुरक्षित संशोधन, व्युत्पन्न कक्षाएँ को अपक्रिया का कारण बन सकता है। प्रोग्रामर यह निर्धारित नहीं कर सकता है कि आधार कक्षा के तरीकों को वियोजन में जांच कर आधार कक्षा परिवर्तन सुरक्षित है या नहीं।


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


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


दुर्बल आधार वर्ग की समस्या को खुले पुनरावर्तन (पर विधियों के गतिशील प्रेषण) पर दोष दिया गया है), इस सुझाव के साथ कि खुले पुनरावर्तन (गतिशील प्रेषण, देर से बाध्यकारी) के अतिरिक्त इस डिफ़ॉल्ट पर बंद पुनरावर्तन (स्थैतिक प्रेषण, प्रारंभिक बाध्यकारी) पर विधियों का निर्देशित किया गया है। केवल खुले पुनरावर्तन का उपयोग करते हुए जब इसे विशेष रूप से बाह्य निर्देश का अनुरोध किया जाता है (इसका उपयोग नहीं किया जाता है) सामान्य रूप से गतिशील रूप से प्रेषित किया जाएगा।<ref>"[https://www.cs.cmu.edu/~aldrich/papers/selective-open-recursion.pdf Selective Open Recursion: A Solution to the Fragile Base Class Problem]", Jonathan Aldrich</ref><ref>"[http://lambda-the-ultimate.org/classic/message12271.html Selective Open Recursion: A Solution to the Fragile Base Class Problem]", ''[http://lambda-the-ultimate.org/ Lambda the Ultimate]''</ref>
दुर्बल आधार कक्षा की समस्या को खुले पुनरावर्तन (पर विधियों के गतिशील प्रेषण) पर दोष दिया गया है), इस सुझाव के साथ कि खुले पुनरावर्तन (गतिशील प्रेषण, देर से बाध्यकारी) के अतिरिक्त इस डिफ़ॉल्ट पर बंद पुनरावर्तन (स्थैतिक प्रेषण, प्रारंभिक बाध्यकारी) पर विधियों का निर्देशित किया गया है। केवल खुले पुनरावर्तन का उपयोग करते हुए जब इसे विशेष रूप से बाह्य निर्देश का अनुरोध किया जाता है (इसका उपयोग नहीं किया जाता है) सामान्य रूप से गतिशील रूप से प्रेषित किया जाएगा।<ref>"[https://www.cs.cmu.edu/~aldrich/papers/selective-open-recursion.pdf Selective Open Recursion: A Solution to the Fragile Base Class Problem]", Jonathan Aldrich</ref><ref>"[http://lambda-the-ultimate.org/classic/message12271.html Selective Open Recursion: A Solution to the Fragile Base Class Problem]", ''[http://lambda-the-ultimate.org/ Lambda the Ultimate]''</ref>




== जावा उदाहरण ==
== जावा उदाहरण ==
निम्नलिखित साधारण उदाहरण [[जावा प्रोग्रामिंग भाषा|जावा प्रोग्राम भाषा]] में लिखा गया है और दिखाता है कि कैसे एक आधार वर्ग का प्रतीत होता है कि सुरक्षित संशोधन एक निहित उप-वर्ग को अनंत पुनरावर्तन में प्रवेश करके अपक्रिया का कारण बन सकता है जिसके परिणामस्वरूप संग्रह की अधिकता होगी।
निम्नलिखित साधारण उदाहरण [[जावा प्रोग्रामिंग भाषा|जावा प्रोग्राम भाषा]] में लिखा गया है और दिखाता है कि कैसे एक आधार कक्षा का प्रतीत होता है कि सुरक्षित संशोधन एक इनहेरिटेंस उप- कक्षा को अनंत पुनरावर्तन में प्रवेश करके अपक्रिया का कारण बन सकता है जिसके परिणामस्वरूप संग्रह की अधिकता होगी।
  class Super {
  class Super {
   
   
Line 34: Line 34:
  }
  }


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


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


== समाधान ==
== समाधान ==
* [[उद्देश्य सी|उद्देश्य-C]] में श्रेणियां और साथ ही गैर-दुर्बल उदाहरण चर हैं।
* [[उद्देश्य सी|उद्देश्य-C]] में श्रेणियां और साथ ही गैर-दुर्बल उदाहरण चर हैं।
* [[घटक पास्कल]] अधिवर्ग (कंप्यूटर विज्ञान) को बहिष्कृत करता है।
* [[घटक पास्कल]] सुपरक्लास (कंप्यूटर विज्ञान) को बहिष्कृत करता है।
* जावा, C++ (C++11 के बाद से) और D "अंतिम" कीवर्ड के साथ क्रमशः वर्ग या विधि की घोषणा को लेबल करके इनहेरिटेंस (वंशानुक्रम) या वर्ग विधि को ओवरराइड करने की स्वीकृति देते हैं। प्रभावी जावा पुस्तक में, लेखक जोशुआ ब्लोच लिखते हैं (वस्तु 17 में) कि प्रोग्रामर को "इनहेरिटेंस के लिए डिजाइन और दस्तावेज या अन्यथा इसे प्रतिबंधित करना चाहिए"।
* जावा, C++ (C++11 के बाद से) और D "अंतिम" कीवर्ड के साथ क्रमशः कक्षा या विधि की घोषणा को लेबल करके इनहेरिटेंस (वंशानुक्रम) या कक्षा विधि को ओवरराइड करने की स्वीकृति देते हैं। प्रभावी जावा पुस्तक में, लेखक जोशुआ ब्लोच लिखते हैं (वस्तु 17 में) कि प्रोग्रामर को "इनहेरिटेंस के लिए डिजाइन और दस्तावेज या अन्यथा इसे प्रतिबंधित करना चाहिए"।
* जावा की तरह C# और VB.NET में इनहेरिटेंस को प्रतिबंधित करने के लिए "मुद्रांकित" और "इनहेरिटेबल नहीं" वर्ग प्रकाशन कीवर्ड हैं, और ओवरराइड विधियों पर कीवर्ड "अधिभूत" का उपयोग करने के लिए उपवर्ग की आवश्यकता होती है, वही समाधान बाद में स्काला द्वारा स्वीकृत किया गया।<ref>{{Cite web | url=https://msdn.microsoft.com/en-us/library/ebca9ah3.aspx | title=Override modifier - C# Reference }}</ref>  
* जावा की तरह C# और VB.NET में इनहेरिटेंस को प्रतिबंधित करने के लिए "मुद्रांकित" और "इनहेरिटेबल नहीं" कक्षा प्रकाशन कीवर्ड हैं, और ओवरराइड विधियों पर कीवर्ड "अधिभूत" का उपयोग करने के लिए उप-कक्षा की आवश्यकता होती है, वही समाधान बाद में स्काला द्वारा स्वीकृत किया गया।<ref>{{Cite web | url=https://msdn.microsoft.com/en-us/library/ebca9ah3.aspx | title=Override modifier - C# Reference }}</ref>  
* स्काला को मूल वर्ग विधि को ओवरराइड करने के लिए स्पष्ट रूप से कीवर्ड "ओवरराइड" का उपयोग करने के लिए एक उपवर्ग की आवश्यकता होती है। "प्रोग्रामिंग इन स्काला, द्वितीय संस्करण" पुस्तक में, लेखक लिखता है कि (यहां संशोधनों के साथ) यदि कोई विधि f() नहीं थी, तो क्लाइंट के विधि f() के मूल कार्यान्वयन में ओवरराइड संशोधक नहीं हो सकता था। एक बार जब आप अपने पुस्तकालय वर्ग के दूसरे संस्करण में f() विधि जोड़ते हैं, तो क्लाइंट कोड का पुन: संकलन गलत गतिविधि के अतिरिक्त संकलन त्रुटि देगा।
* स्काला को मूल कक्षा विधि को ओवरराइड करने के लिए स्पष्ट रूप से कीवर्ड "ओवरराइड" का उपयोग करने के लिए एक उप-कक्षा की आवश्यकता होती है। "प्रोग्रामिंग इन स्काला, द्वितीय संस्करण" पुस्तक में, लेखक लिखता है कि (यहां संशोधनों के साथ) यदि कोई विधि f() नहीं थी, तो क्लाइंट के विधि f() के मूल कार्यान्वयन में ओवरराइड संशोधक नहीं हो सकता था। एक बार जब आप अपने पुस्तकालय कक्षा के दूसरे संस्करण में f() विधि जोड़ते हैं, तो क्लाइंट कोड का पुन: संकलन गलत गतिविधि के अतिरिक्त संकलन त्रुटि देगा।
* कोटलिन में कक्षाएं और विधियां डिफ़ॉल्ट रूप से अंतिम होती हैं। वर्ग वंशानुक्रम को सक्षम करने के लिए, वर्ग को खुले संशोधक के साथ चिह्नित किया जाना चाहिए। इसी तरह, विधि को ओवरराइड करने की स्वीकृति देने के लिए एक विधि को खुले के रूप में चिह्नित किया जाना चाहिए।
* कोटलिन में कक्षाएं और विधियां डिफ़ॉल्ट रूप से अंतिम होती हैं। कक्षा वंशानुक्रम को सक्षम करने के लिए, कक्षा को खुले संशोधक के साथ चिह्नित किया जाना चाहिए। इसी तरह, विधि को ओवरराइड करने की स्वीकृति देने के लिए एक विधि को खुले के रूप में चिह्नित किया जाना चाहिए।
* जूलिया (प्रोग्राम भाषा) अमूर्त प्रकारों के केवल उप-प्रकार की स्वीकृति देता है और [[वंशानुक्रम (वस्तु-उन्मुख प्रोग्रामिंग)|इनहेरिटेंस (वस्तु-उन्मुख प्रोग्राम)]] के विकल्प के रूप में रचना का उपयोग करता है। हालाँकि इसमें कई प्रेषण हैं।
* जूलिया (प्रोग्राम भाषा) अमूर्त प्रकारों के केवल उप-प्रकार की स्वीकृति देता है और [[वंशानुक्रम (वस्तु-उन्मुख प्रोग्रामिंग)|इनहेरिटेंस (वस्तु-उन्मुख प्रोग्राम)]] के विकल्प के रूप में रचना का उपयोग करता है। हालाँकि इसमें कई प्रेषण हैं।



Revision as of 13:48, 18 February 2023

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

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

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

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

दुर्बल आधार कक्षा की समस्या को खुले पुनरावर्तन (पर विधियों के गतिशील प्रेषण) पर दोष दिया गया है), इस सुझाव के साथ कि खुले पुनरावर्तन (गतिशील प्रेषण, देर से बाध्यकारी) के अतिरिक्त इस डिफ़ॉल्ट पर बंद पुनरावर्तन (स्थैतिक प्रेषण, प्रारंभिक बाध्यकारी) पर विधियों का निर्देशित किया गया है। केवल खुले पुनरावर्तन का उपयोग करते हुए जब इसे विशेष रूप से बाह्य निर्देश का अनुरोध किया जाता है (इसका उपयोग नहीं किया जाता है) सामान्य रूप से गतिशील रूप से प्रेषित किया जाएगा।[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".


बाहरी संबंध