जब हम एक वर्ग बनाते हैं जो एक अमूर्त वर्ग से विरासत में मिलता है और जब हम विरासत में मिली अमूर्त कक्षा को लागू करते हैं तो हमें ओवरराइड कीवर्ड का उपयोग क्यों करना पड़ता है?
"क्यों?" इस तरह के सवालों का जवाब देना मुश्किल हो सकता है क्योंकि वे अस्पष्ट हैं। मैं यह मानने जा रहा हूं कि आपका प्रश्न "भाषा डिज़ाइन के दौरान उस स्थिति के लिए तर्क देने के लिए क्या तर्क दिए जा सकते हैं जो overrideकीवर्ड की आवश्यकता है ?"
चलो एक कदम पीछे ले जाकर शुरू करते हैं। कुछ भाषाओं में, कहते हैं, जावा, विधियाँ डिफ़ॉल्ट रूप से आभासी हैं और स्वचालित रूप से ओवरराइड की जाती हैं। C # के डिज़ाइनर इसके बारे में जानते थे और इसे जावा में एक मामूली दोष मानते थे। C # को "बाहर निकाले गए बेवकूफ हिस्सों के साथ जावा" नहीं कहा गया है, जैसा कि कुछ ने कहा है, लेकिन C # के डिज़ाइनर C, C ++ और Java के समस्याग्रस्त डिज़ाइन बिंदुओं से सीखने के इच्छुक थे, और C # में उनकी प्रतिकृति नहीं बनाते थे।
C # डिजाइनरों ने ओवरराइडिंग को कीड़े का एक संभावित स्रोत माना; आखिरकार, यह मौजूदा, परीक्षण किए गए कोड के व्यवहार को बदलने का एक तरीका है , और यह खतरनाक है। ओवरराइडिंग ऐसी चीज नहीं है जिसे आकस्मिक रूप से या दुर्घटना से किया जाना चाहिए; इसे किसी व्यक्ति द्वारा इसके बारे में कठिन सोचकर बनाया जाना चाहिए । यही कारण है कि विधियां डिफ़ॉल्ट रूप से आभासी नहीं हैं, और आपको यह कहने की आवश्यकता क्यों है कि आप एक विधि को ओवरराइड कर रहे हैं।
यही मूल तर्क है। अब हम कुछ और उन्नत तर्क में जा सकते हैं।
स्ट्रिप्लिंगवर्यर का जवाब एक और अधिक उन्नत तर्क देने के लिए एक अच्छा पहला कट देता है। व्युत्पन्न वर्ग के लेखक को बेस क्लास के बारे में जानकारी नहीं दी जा सकती है, एक नई विधि बनाने का इरादा हो सकता है, और हमें उपयोगकर्ता को गलती से ओवरराइड करने की अनुमति नहीं देनी चाहिए। ।
हालाँकि यह बिंदु वाजिब है, कई प्रतिवाद हैं, जैसे:
- एक व्युत्पन्न वर्ग के लेखक के पास बेस क्लास के बारे में सब कुछ जानने की जिम्मेदारी है ! वे उस कोड का फिर से उपयोग कर रहे हैं, और उन्हें उस कोड को दोबारा उपयोग करने से पहले उस कोड को अच्छी तरह से समझने के लिए उचित परिश्रम करना चाहिए।
- आपके विशेष परिदृश्य में वर्चुअल विधि अमूर्त है; यह इसे ओवरराइड नहीं करने के लिए एक त्रुटि होगी , और इसलिए यह संभावना नहीं है कि लेखक दुर्घटना से एक कार्यान्वयन बना रहा होगा।
चलिए फिर इस बिंदु पर एक और अधिक उन्नत तर्क बनाते हैं। आधार वर्ग क्या करता है यह जानने के लिए किसी व्युत्पन्न वर्ग के लेखक को किन परिस्थितियों में बहाना हो सकता है? इस परिदृश्य पर विचार करें:
- बेस क्लास लेखक एक सार बेस क्लास बी बनाता है।
- एक अलग टीम पर व्युत्पन्न वर्ग लेखक, विधि एम के साथ एक व्युत्पन्न वर्ग डी बनाता है।
- बेस क्लास लेखक को पता चलता है कि बेस क्लास बी का विस्तार करने वाली टीमों को हमेशा एक विधि एम की आपूर्ति करने की आवश्यकता होगी, इसलिए बेस क्लास लेखक ने अमूर्त एम।
- जब क्लास डी को दोबारा शुरू किया जाता है, तो क्या होता है?
हम जो चाहते हैं, वह है डी के लेखक को सूचित किया जाता है कि कुछ प्रासंगिक बदल गया है । जो प्रासंगिक बात बदल गई है, वह यह है कि एम अब एक आवश्यकता है और उनका कार्यान्वयन अतिभारित होना चाहिए। डीएम को अपने व्यवहार को बदलने की आवश्यकता हो सकती है क्योंकि हम जानते हैं कि इसे आधार वर्ग से बुलाया जा सकता है। सही बात यह है कि चुपचाप नहीं कहना है "ओह, डीएम मौजूद है और बीएम का विस्तार करता है"। संकलक के लिए सही काम विफल है , और कहते हैं , "हे, डी के लेखक, तुम्हारी इस धारणा को देखें जो अब मान्य नहीं है और यदि आवश्यक हो तो अपने कोड को ठीक करें"।
आपके उदाहरण में, मान लीजिए कि overrideयह वैकल्पिक था SayHelloक्योंकि यह एक अमूर्त विधि से आगे निकल रहा है। दो संभावनाएँ हैं: (1) कोड का लेखक एक अमूर्त विधि को ओवरराइड करने का इरादा रखता है, या (2) ओवरराइडिंग विधि दुर्घटना से आगे निकल रही है क्योंकि किसी और ने आधार वर्ग को बदल दिया है, और कोड अब कुछ सूक्ष्म तरीके से गलत है। यदि overrideवैकल्पिक हो तो हम इन संभावनाओं को नहीं बता सकते ।
लेकिन अगर override है की आवश्यकता तो हम अलग तीन परिदृश्य बता सकते हैं। अगर वहाँ कोड में संभावित गलती है तो overrideहै याद आ रही । यह जानबूझकर अधिभावी रहा है तो overrideहै वर्तमान । और अगर यह जानबूझकर किया गया है नहीं अधिभावी तो newहै वर्तमान । C # का डिज़ाइन हमें इन सूक्ष्म भेदों को बनाने में सक्षम बनाता है।
याद रखें कंपाइलर त्रुटि रिपोर्टिंग को डेवलपर के दिमाग को पढ़ने की आवश्यकता होती है ; कंपाइलर को गलत कोड से हटना होगा जो लेखक के सही कोड को ध्यान में रखता है , और एक त्रुटि देता है जो उन्हें सही दिशा में इंगित करता है। अधिक सुराग हम डेवलपर को उस कोड के बारे में बता सकते हैं जो वे सोच रहे थे, संकलक रिपोर्ट त्रुटियों में बेहतर काम कर सकता है और इसलिए जितनी तेज़ी से आप अपने कीड़े पा सकते हैं और ठीक कर सकते हैं।
लेकिन आम तौर पर, C # एक ऐसी दुनिया के लिए डिज़ाइन किया गया था जिसमें कोड बदलता है । C # की एक बहुत सी विशेषताएं जो "अजीब" दिखाई देती हैं, वास्तव में वहां होती हैं क्योंकि वे डेवलपर को सूचित करती हैं जब एक धारणा जो वैध हुआ करती थी वह अमान्य हो गई क्योंकि एक आधार वर्ग बदल गया। बगों के इस वर्ग को "भंगुर आधार वर्ग की विफलताएं" कहा जाता है, और इस विफलता वर्ग के लिए C # में कई दिलचस्प मिथिगेशन हैं।