जावा और C # के बीच एक छोटा सा अंतर है जो यहां प्रासंगिक है। जावा में, हर सदस्य डिफ़ॉल्ट रूप से आभासी है। C # में, प्रत्येक सदस्य को डिफ़ॉल्ट रूप से सील किया जाता है - इंटरफ़ेस सदस्यों को छोड़कर।
इस धारणा के साथ चलने वाली धारणाएँ दिशानिर्देश - जावा में, हर सार्वजनिक प्रकार को गैर-अंतिम माना जाना चाहिए, जो लिस्कोव के प्रतिस्थापन सिद्धांत [1] के अनुसार है। यदि आपके पास केवल एक कार्यान्वयन है, तो आप कक्षा का नाम देंगे Parser
; यदि आपको लगता है कि आपको कई कार्यान्वयन की आवश्यकता है, तो आप कक्षा को एक ही नाम के साथ एक इंटरफ़ेस में बदल देंगे, और कुछ कार्यान्वयन के लिए ठोस कार्यान्वयन का नाम बदल देंगे।
C # में, मुख्य धारणा यह है कि जब आप एक वर्ग प्राप्त करते हैं (नाम के साथ शुरू नहीं होता है I
), तो आप जिस वर्ग को चाहते हैं। ध्यान रखें, यह कहीं भी 100% सटीक नहीं है - एक विशिष्ट प्रति-उदाहरण वर्ग होगा Stream
( जैसे कि वास्तव में एक इंटरफ़ेस, या कुछ इंटरफेस होना चाहिए), और सभी के पास अन्य भाषाओं के अपने दिशानिर्देश और पृष्ठभूमि हैं। Base
अमूर्त वर्ग को निरूपित करने के लिए काफी व्यापक रूप से इस्तेमाल किए जाने वाले प्रत्यय जैसे अन्य अपवाद भी हैं - जैसे कि एक इंटरफ़ेस के साथ, आप जानते हैं कि प्रकार को बहुरूपी माना जाता है।
कार्यक्षमता के लिए गैर- I- उपसर्ग नाम छोड़ने में भी एक अच्छा प्रयोज्य सुविधा है जो इंटरफ़ेस को एक सार वर्ग बनाने के लिए सहारा के बिना संबंधित है (जो कि सी # में कई-विरासत के वर्ग की कमी के कारण चोट लगी होगी)। यह LINQ द्वारा लोकप्रिय किया गया था, जो IEnumerable<T>
इंटरफ़ेस के रूप में उपयोग करता है, और Enumerable
उस इंटरफ़ेस पर लागू होने वाले तरीकों के भंडार के रूप में। यह जावा में अनावश्यक है, जहां इंटरफेस में विधि कार्यान्वयन भी हो सकता है।
अंततः, I
C # दुनिया में उपसर्ग का व्यापक रूप से उपयोग किया जाता है, और एक्सटेंशन के द्वारा, .NET दुनिया (क्योंकि अब तक अधिकांश .NET कोड C # में लिखे गए हैं, यह अधिकांश सार्वजनिक इंटरफेस के लिए C # दिशा-निर्देशों का पालन करने के लिए समझ में आता है)। इसका मतलब है कि आप लगभग निश्चित रूप से पुस्तकालयों और कोड के साथ काम कर रहे होंगे जो इस संकेतन का अनुसरण करते हैं, और यह अनावश्यक भ्रम को रोकने के लिए परंपरा को अपनाने के लिए समझ में आता है - यह उपसर्ग को छोड़ने की तरह नहीं है जो आपके कोड को किसी भी बेहतर बना देगा :)
मुझे लगता है कि अंकल बॉब का तर्क कुछ इस तरह था:
IBanana
केला की अमूर्त धारणा है। यदि कोई लागू करने वाला वर्ग हो सकता है जिसका कोई बेहतर नाम नहीं है Banana
, तो अमूर्त पूरी तरह से व्यर्थ है, और आपको इंटरफ़ेस को छोड़ देना चाहिए और बस एक वर्ग का उपयोग करना चाहिए। यदि कोई बेहतर नाम (कहते हैं, LongBanana
या AppleBanana
) है, Banana
तो इंटरफ़ेस के नाम के रूप में उपयोग नहीं करने का कोई कारण नहीं है । इसलिए, I
उपसर्ग का उपयोग यह दर्शाता है कि आपके पास एक बेकार अमूर्त है, जो कोड को बिना किसी लाभ के साथ समझने में कठिन बनाता है। और जब से सख्त ओओपी आपके पास हमेशा इंटरफेस के खिलाफ कोड होगा, एकमात्र स्थान जहां आप I
एक प्रकार पर उपसर्ग नहीं देखेंगे, एक निर्माता पर होगा - काफी व्यर्थ शोर।
यदि आप इसे अपने नमूना IParser
इंटरफ़ेस पर लागू करते हैं , तो आप स्पष्ट रूप से देख सकते हैं कि अमूर्तता पूरी तरह से "अर्थहीन" क्षेत्र में है। या तो वहाँ एक पार्सर (जैसे की एक ठोस कार्यान्वयन के बारे में कुछ विशिष्ट है JsonParser
, XmlParser
...), या तुम सिर्फ एक वर्ग का उपयोग करना चाहिए। "डिफ़ॉल्ट कार्यान्वयन" जैसी कोई चीज नहीं है (हालांकि कुछ वातावरणों में, यह वास्तव में समझ में आता है - विशेष रूप से, COM), या तो एक विशिष्ट कार्यान्वयन है, या आप "चूक" के लिए एक सार वर्ग या विस्तार के तरीके चाहते हैं। हालाँकि, C # में, जब तक कि आपका कोडबेस पहले से I
-प्रिफ़िक्स को छोड़ नहीं देता है, तब तक रखें। बस हर बार एक मानसिक नोट बनाएं जैसे कि आपको कोड दिखाई देता है class Something: ISomething
- इसका मतलब है कि कोई व्यक्ति YAGNI का अनुसरण करने और उचित सार का निर्माण करने में बहुत अच्छा नहीं है।
[१] - तकनीकी रूप से, यह विशेष रूप से लिस्कोव के कागज में उल्लिखित नहीं है, लेकिन यह मूल ओओपी पेपर की नींव में से एक है और लिस्कोव के मेरे पढ़ने में, उसने इसे चुनौती नहीं दी। कम सख्त व्याख्या में (अधिकांश ओओपी भाषाओं द्वारा लिया गया), इसका मतलब है कि किसी भी सार्वजनिक प्रकार का उपयोग करने वाला कोड जो प्रतिस्थापन के लिए अभिप्रेत है (यानी गैर-अंतिम / सील) उस प्रकार के किसी भी अनुरूप कार्यान्वयन के साथ काम करना चाहिए।