इंटरफेस क्यों उपयोगी हैं?


158

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

C # एक महान भाषा है, लेकिन कभी-कभी यह आपको यह एहसास दिलाता है कि पहले Microsoft समस्या का निर्माण करता है (एकाधिक वंशानुक्रम की अनुमति नहीं देता है) और फिर समाधान प्रदान करता है, जो एक थकाऊ है।

यह मेरी समझ है जो सीमित कोडिंग अनुभव पर आधारित है। आपके इंटरफेस पर क्या है? आप कितनी बार उनका उपयोग करते हैं और आप ऐसा क्या करते हैं?


55
"यदि मुझे उन कार्यों के नाम और हस्ताक्षर याद हो सकते हैं जिन्हें लागू करने की आवश्यकता है, तो उनकी कोई आवश्यकता नहीं है।" यह कथन मुझे संदेह करता है कि आपको सांख्यिकीय रूप से टाइप की गई भाषाओं के फायदे में थोड़ा और देखना चाहिए ।
स्टीवन ज्यूरी

37
C # को भूल जाओ, जावा को भूल जाओ, भाषा को भूल जाओ। यह केवल OO के संदर्भ में सोच रहा है। मैं आपको रॉबर्ट सी। मार्टिन, मार्टिन फाउलर, माइकल फेयर्स, द गैंग ऑफ फोर, आदि जैसे लोगों से कुछ पठन सामग्री लेने के लिए प्रोत्साहित करूंगा, क्योंकि यह आपकी सोच का विस्तार करने में मदद करेगा।
एंथनी Pegram

27
मुझे यह समझने में दो साल से अधिक समय लगा कि इंटरफेस किस लिए अच्छे हैं। मेरा सुझाव: अध्ययन डिजाइन पैटर्न। जैसा कि उनमें से अधिकांश इंटरफेस पर भरोसा करते हैं, आप जल्दी से समझ जाएंगे कि वे इतने उपयोगी क्यों हैं।
ओलिवर वीलर

37
आपको दोस्त सीखने के लिए बहुत कुछ मिला है।
चोसपंडियन

60
@ChaosPandion हम सभी को बहुत कुछ सीखने को मिला है
kenwarner

जवाबों:


151

वे केवल यह सुनिश्चित करने के लिए हैं कि उक्त कार्य (इंटरफ़ेस में) विरासत श्रेणी में लागू किए गए हैं।

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

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

C # एक महान भाषा है, लेकिन कभी-कभी यह आपको यह एहसास दिलाता है कि पहले Microsoft समस्या का निर्माण करता है (एकाधिक उत्तराधिकार की अनुमति नहीं देता है) और फिर समाधान प्रदान करता है, जो एक थकाऊ है।

वैसे मुझे खुशी है कि आप इसे पसंद करेंगे।

सभी जटिल सॉफ़्टवेयर डिज़ाइन एक-दूसरे के खिलाफ परस्पर विरोधी सुविधाओं को तौलने और "मीठे स्थान" को खोजने की कोशिश करने का एक परिणाम है जो छोटी लागतों के लिए बड़े लाभ देता है। हमने दर्दनाक अनुभव के माध्यम से सीखा है कि कार्यान्वयन साझाकरण के प्रयोजनों के लिए कई विरासत की अनुमति देने वाली भाषाओं में अपेक्षाकृत छोटे लाभ और अपेक्षाकृत बड़ी लागतें हैं। केवल इंटरफेस पर कई विरासत की अनुमति, जो कार्यान्वयन विवरण साझा नहीं करते हैं, अधिकांश लागतों के बिना कई विरासत के कई लाभ देते हैं।


मैं सिर्फ यह पढ़ रहा था "Microsoft एकाधिक वंशानुक्रम की अनुमति न देकर समस्या पैदा करता है" और मुझे लगा कि एरिक लिपर्ट के पास इसके बारे में कुछ कहने के लिए होगा।
विन्यासकर्ता

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

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

2
मैं यह महसूस करने की उम्मीद करता हूं कि जब कोई विधि यह वादा करती है कि परिणाम सरणी या गणना में शून्य नहीं है, तो विधि का उपयोग उन स्थानों में मूल्यों का उपयोग कर सकता है जो नल की अनुमति नहीं देते हैं। यह एक ऐसी चीज है जिसकी मुझे उम्मीद थी कि यह ऐसा होगा, और इसके बिना उपयोग करने योग्य होना बहुत महत्वपूर्ण है; कुछ और सिर्फ एक बोनस है। उस ने कहा, मुझे पता है कि स्थैतिक सत्यापन पूरा नहीं हो सकता है, यही कारण है कि मुझे लगता है कि यह अनुबंधों पर भरोसा करने का एक अच्छा विकल्प नहीं है।
विन्यासकर्ता

9
+1 के लिए "वैसे मुझे खुशी है कि आप इसे पसंद करेंगे।" और बाकी सभी सामान भी।
रॉबर्ट एस।

235

यहां छवि विवरण दर्ज करें

इसलिए इस उदाहरण में, PowerSocket को अन्य वस्तुओं के बारे में और कुछ नहीं पता है। सभी वस्तुएँ PowerSocket द्वारा प्रदत्त पावर पर निर्भर करती हैं, इसलिए वे IPowerPlug को लागू करते हैं, और ऐसा करने में वे इससे जुड़ सकते हैं।

इंटरफेस उपयोगी होते हैं क्योंकि वे ऐसे अनुबंध प्रदान करते हैं जो ऑब्जेक्ट एक-दूसरे के बारे में कुछ और जानने की आवश्यकता के बिना एक साथ काम करने के लिए उपयोग कर सकते हैं।


4
नीचे की बाईं वस्तु ऐसा नहीं लगता है कि यह IPowerPlug =) को लागू करता है
स्टीवन स्ट्रिगा

100
लानत है, लेकिन हमें विभिन्न देशों में IPowerPlug का उपयोग करने के लिए एक एडेप्टर पैटर्न का उपयोग करना होगा!
स्टीवन ज्यूरिस

जेरी-हेराफेरी करने के लिए इंटरफ़ेस के आसपास काम करने के लिए एक उपकरण सुरक्षित नहीं है (लेकिन कुछ लोग अभी भी इसे अक्सर एक निष्कासित बहाने के रूप में प्रदर्शन का हवाला देते हैं), और आग लगने की संभावना है।
यंगजॉन

4
यह जवाब सिर्फ आश्चर्यजनक है ...
मारियो गार्सिया

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

145

फ़ंक्शन के हस्ताक्षर प्रदान करने के अलावा, वे कुछ भी नहीं करते हैं। अगर मुझे उन कार्यों के नाम और हस्ताक्षर याद हो सकते हैं जिन्हें लागू करने की आवश्यकता है, तो उनकी कोई आवश्यकता नहीं है

इंटरफेस की बात यह है कि आपको यह याद रखने में मदद नहीं करनी है कि किस पद्धति को लागू करना है, यह एक अनुबंध को परिभाषित करने के लिए यहां है । में foreach P.Brian.Mackey उदाहरण (जो पता चला है गलत होने के लिए है, लेकिन हम परवाह नहीं है), IEnumerable के बीच एक अनुबंध को परिभाषित करता है foreach और किसी भी गणनीय बात। यह कहता है: "आप जो भी हैं, जब तक आप अनुबंध (IEnumerable लागू करें) से चिपके रहते हैं, मैं वादा करता हूँ कि मैं आपके सभी तत्वों पर पुनरावृति करूँगा"। और, यह महान है (एक गैर गतिशील भाषा के लिए)।

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



मैं "बतख टाइपिंग" शब्द का उपयोग करना पसंद नहीं करता क्योंकि इसका मतलब अलग-अलग लोगों के लिए अलग-अलग चीजें हैं। हम "फॉर्च्यूनर" लूप के लिए पैटर्न के मिलान का उपयोग करते हैं क्योंकि जब इसे डिजाइन किया गया था, IEnumerable <T> अनुपलब्ध था। हम LINQ के लिए मैचिंग पैटर्न का उपयोग करते हैं क्योंकि C # टाइप सिस्टम "monad pattern" को कैप्चर करने के लिए बहुत कमजोर है। आपको हास्केल प्रकार प्रणाली की तरह कुछ चाहिए।
एरिक लिपर्ट

@ Eric: "पैटर्न मिलान" एक ही समस्या नहीं है? जब मैं इसे सुनता हूं तो मुझे लगता है कि एफ # / स्काला / हास्केल। लेकिन मुझे लगता है कि यह बतख-टाइपिंग की तुलना में एक व्यापक विचार है।
डैनियल

@ डैनियल: हाँ, मुझे लगता है कि यह करता है। इसके छह में से एक और आधा दर्जन मुझे लगता है!
एरिक लिपर्ट

36

Interfaces अच्छी तरह से decoupled निर्माण को बनाए रखने के लिए सबसे अच्छा तरीका है।

परीक्षण लिखते समय, आप पाएंगे कि आपके परीक्षण वातावरण में ठोस कक्षाएं काम नहीं करेंगी।

उदाहरण: आप एक वर्ग का परीक्षण करना चाहते हैं जो डेटा एक्सेस सर्विस क्लास पर निर्भर करता है । यदि वह वर्ग किसी वेब सेवा, या डेटाबेस से बात कर रहा है - तो आपकी इकाई परीक्षा आपके परीक्षण वातावरण में नहीं चलेगी (साथ ही यह एकीकरण में बदल गई है)।

उपाय? अपनी डेटा एक्सेस सेवा के लिए एक इंटरफ़ेस का उपयोग करें और उस इंटरफ़ेस को मॉक करें ताकि आप अपनी कक्षा को एक इकाई के रूप में परख सकें।

दूसरी ओर, WPF और सिल्वरलाइट बाइंडिंग की बात आने पर इंटरफेसेस के साथ बिल्कुल नहीं खेलते हैं। यह एक बहुत बुरा शिकन है।


2
सुनो सुनो! अन्य समस्याओं, जैसे बहुरूपता को हल करने के लिए इंटरफेस का आविष्कार किया गया था। हालांकि, मेरे लिए, वे एक डिपेंडेंसी इंजेक्शन पैटर्न को लागू करते समय स्वयं में आते हैं।
एंडी

29

इंटरफेस (स्थिर) बहुरूपता की रीढ़ हैं! इंटरफ़ेस क्या मायने रखता है। वंशानुक्रम इंटरफेस के बिना काम नहीं करेगा, क्योंकि उपवर्ग मूल रूप से माता-पिता के पहले से लागू इंटरफ़ेस को विरासत में मिला है।

आप कितनी बार उनका उपयोग करते हैं और क्या आप ऐसा करते हैं ??

बहुत बार। जो कुछ भी प्लग-इन करने की आवश्यकता है वह मेरे अनुप्रयोगों में एक इंटरफ़ेस है। कई बार आपके पास अन्यथा असंबद्ध वर्ग होते हैं जिन्हें समान व्यवहार प्रदान करने की आवश्यकता होती है। आप विरासत के साथ ऐसी समस्याओं को हल नहीं कर सकते।

एक ही डेटा पर संचालन करने के लिए अलग-अलग एल्गोरिदम की आवश्यकता है? एक इंटरफ़ेस का उपयोग करें ( रणनीति पैटर्न देखें )!

क्या आप विभिन्न सूची कार्यान्वयन का उपयोग करना चाहते हैं? एक इंटरफ़ेस के खिलाफ कोड और फोन करने वाले को कार्यान्वयन के बारे में चिंता करने की आवश्यकता नहीं है!

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


1
कभी बहुरूपता के बारे में नहीं सुना, आप बहुरूपता का मतलब?
स्टीवन ज्यूरी

1
कहा जा रहा है कि, यदि Microsoft पहले स्थान पर कई विरासतों की अनुमति देता है, तो इंटरफेस के अस्तित्व का कोई कारण नहीं होगा
पंकज उपाध्याय

10
@ पंकज उपाध्याय: एकाधिक विरासत और इंटरफेस दो अलग-अलग जोड़े जूते हैं। यदि आपको अलग-अलग व्यवहार वाले दो असंबंधित वर्गों के इंटरफ़ेस की आवश्यकता है तो क्या होगा? आप इसे कई उत्तराधिकारियों द्वारा हल नहीं कर सकते। आप इसे वैसे भी अलग से लागू कर सकते हैं। और फिर आपको पॉलिमॉर्फिक व्यवहार प्रदान करने के लिए इंटरफ़ेस का वर्णन करने के लिए कुछ की आवश्यकता होगी। मल्टीपल इनहेरिटेंस कई मामलों में नीचे चलने के लिए एक अंधे गली है, और बहुत जल्दी या बाद में अपने आप को पैर में गोली मारना बहुत आसान है।
फाल्कन

1
सरल बनाने देता है। यदि मेरा इंटरफ़ेस दो फ़ंक्शन प्रदर्शित करता है और टिप्पणी करता है, और मेरे पास एक वर्ग है जो उन्हें लागू करता है। फिर मैं इंटरफ़ेस क्यों नहीं हटाता और सीधे फ़ंक्शन का उपयोग करता हूं। मैं यह कह रहा हूं कि वे आपको केवल उन कार्यों के नाम प्रदान कर रहे हैं जिन्हें लागू करने की आवश्यकता है। यदि कोई उन कार्यों को याद कर सकता है तो एक इंटरफ़ेस क्यों बनाएं
पंकज उपाध्याय

9
@ पंकज, अगर वह सब है जिसके लिए आपको इंटरफ़ेस की आवश्यकता है, तो इसका उपयोग न करें। जब आप एक प्रोग्राम का उपयोग करते हैं, तो आप एक इंटरफ़ेस का उपयोग करते हैं, जो कक्षा के हर पहलू से अनभिज्ञ होना चाहता है और इसे अपने आधार प्रकार, अर्थात इंटरफ़ेस द्वारा एक्सेस करता है। उन्हें किसी भी उपवर्ग को जानने की आवश्यकता नहीं है, बस यह इंटरफ़ेस के प्रकार का है। जैसे, आप ऑब्जेक्ट के इंटरफ़ेस के संदर्भ में उप-वर्ग के कार्यान्वित विधि को कॉल कर सकते हैं। यह बुनियादी विरासत और डिजाइन सामान है। इसके बिना, आप सी का उपयोग भी कर सकते हैं। भले ही आप स्पष्ट रूप से इसका उपयोग न करें, फ्रेमवर्क इसके बिना काम नहीं करेगा।
जोनाथन हेंसन

12

आपने शायद इसका उपयोग किया है foreachऔर इसे एक बहुत उपयोगी पुनरावृत्ति उपकरण माना है। क्या आप जानते हैं कि इसे कार्य करने के लिए एक इंटरफ़ेस की आवश्यकता है, IEnumerable ?

यह निश्चित रूप से एक ठोस मामला है जो एक इंटरफ़ेस की उपयोगिता के लिए बोल रहा है।


5
वास्तव में, foreach के लिए IEnumerable की आवश्यकता नहीं होती है: msdn.microsoft.com/en-us/library/9yb8xew9%28VS.80%29.aspx
मैट एच

1
मैंने वह सब अध्ययन किया है लेकिन यह दूसरे हाथ से कान को पकड़ने जैसा है। यदि एकाधिक वंशानुक्रम की अनुमति दी गई थी, तो इंटरफ़ेस एक दूर का विकल्प होगा।
पंकज उपाध्याय

2
इंटरफेस कई विरासत हैं, कुछ ऐसा जिसे अक्सर भुला दिया जाता है। हालांकि, वे व्यवहार और राज्य के कई उत्तराधिकार की अनुमति नहीं देते हैं। मिश्रण या लक्षण व्यवहार के कई उत्तराधिकार की अनुमति देते हैं, लेकिन साझा नहीं किए जाते हैं जो मुद्दों का कारण बनता है: en.wikipedia.org/wiki/Mixin
मैट एच

@ पंकज, आपत्तिजनक, लेकिन क्या आपको लगता है कि अगर मैं पूछूं कि आपकी मूल भाषा क्या है? "दूसरे हाथ से कान पकड़ना" एक महान मुहावरा है और मैं उत्सुक था कि यह कहाँ से आता है।
केविन

3
@Iceman। LOL .... मैं भारत से हूँ। और यहाँ यह एक सामान्य मुहावरा है जो आसान चीजों को कठिन तरीके से करने को दर्शाता है।
पंकज उपाध्याय

11

इंटरफेस वस्तुओं को कोडिंग करने के लिए होते हैं जैसे एक प्लग घरेलू तारों के लिए होता है। क्या आप अपने रेडियो को सीधे अपने घर की वायरिंग में मिलाप करेंगे? कैसे अपने वैक्यूम क्लीनर के बारे में? बिलकूल नही। प्लग, और जिस आउटलेट में यह फिट बैठता है, वह आपके घर की वायरिंग और उस डिवाइस के बीच "इंटरफ़ेस" बनाता है, जिसमें से बिजली की आवश्यकता होती है। आपके घर के तारों को डिवाइस के बारे में कुछ भी जानने की जरूरत नहीं है, इसके अलावा यह तीन-आयामी ग्राउंडेड प्लग का उपयोग करता है और 120VAC <= 15A पर विद्युत शक्ति की आवश्यकता होती है। इसके विपरीत, डिवाइस को इस बात की कोई जानकारी नहीं होती है कि आपके घर को किस तरह से तारांकित किया गया है, इसके अलावा इसमें एक या एक से अधिक तीन-आयामी आउटलेट स्थित हैं जो आसानी से 120VAC <= 15A प्रदान करते हैं।

इंटरफेस कोड में एक समान कार्य करते हैं। ऑब्जेक्ट घोषित कर सकता है कि एक विशेष चर, पैरामीटर या रिटर्न प्रकार एक इंटरफ़ेस प्रकार का है। इंटरफ़ेस को सीधे किसी newकीवर्ड के साथ त्वरित नहीं किया जा सकता है , लेकिन मेरी ऑब्जेक्ट को दिया जा सकता है, या मिल सकता है, उस इंटरफ़ेस का कार्यान्वयन जिसे इसके साथ काम करने की आवश्यकता होगी। एक बार जब ऑब्जेक्ट की निर्भरता हो जाती है, तो उसे यह जानने की ज़रूरत नहीं है कि निर्भरता क्या है, बस यह जानना होगा कि यह निर्भरता पर एक्स, वाई और जेड के तरीकों को कॉल कर सकता है। इंटरफ़ेस के कार्यान्वयन को यह जानने की ज़रूरत नहीं है कि उनका उपयोग कैसे किया जाएगा, उन्हें बस यह जानना होगा कि उन्हें विशेष हस्ताक्षर के साथ एक्स, वाई और जेड तरीके प्रदान करने की उम्मीद होगी।

इस प्रकार, एक ही इंटरफ़ेस के पीछे कई ऑब्जेक्ट्स को अमूर्त करके, आप उस इंटरफ़ेस के ऑब्जेक्ट के किसी भी उपभोक्ता को कार्यक्षमता का एक सामान्य सेट प्रदान करते हैं। आपको यह जानने की जरूरत नहीं है कि वस्तु क्या है, उदाहरण के लिए, एक सूची, एक शब्दकोश, एक लिंक्डलिस्ट, एक ऑर्डरेडलिस्ट, या जो भी हो। क्योंकि आप जानते हैं कि ये सभी IEnumerables हैं, आप IEnumerable के तरीकों का उपयोग इन संग्रह में प्रत्येक तत्व के माध्यम से एक बार में करने के लिए कर सकते हैं। आपको यह जानने की ज़रूरत नहीं है कि एक आउटपुट क्लास एक ConsoleWriter, एक FileWriter, एक NetworkStreamWriter, या एक MulticastWriter है जो अन्य प्रकार के लेखकों को लेता है; आप सभी को पता है कि वे सभी IWriters (या जो कुछ भी) हैं, और इस प्रकार उनके पास एक "लिखें" विधि है जिसे आप एक स्ट्रिंग में पास कर सकते हैं, और यह स्ट्रिंग आउटपुट होगा।


7

हालांकि यह स्पष्ट रूप से प्रोग्रामर के लिए एक उपचार है (पहले, कम से कम) कई उत्तराधिकार होने के लिए, यह लगभग तुच्छ चूक है, और आपको (ज्यादातर मामलों में) कई विरासत पर भरोसा नहीं करना चाहिए। इसके कारण जटिल हैं, लेकिन अगर आप वास्तव में इसके बारे में सीखना चाहते हैं, तो दो सबसे प्रसिद्ध ( TIOBE सूचकांक ) प्रोग्रामिंग भाषाओं से अनुभव पर विचार करें जो इसका समर्थन करते हैं: C ++ और पायथन (3 और 8 वां सम्मानपूर्वक)।

पायथन में, कई विरासत का समर्थन किया जाता है, फिर भी प्रोग्रामर द्वारा लगभग सार्वभौमिक रूप से गलत समझा जाता है और यह बताने के लिए कि आप जानते हैं कि यह कैसे काम करता है, इस विषय पर इस पेपर को पढ़ने और समझने का मतलब है: विधि रिज़ॉल्यूशन ऑर्डर । कुछ और, जो कि पायथन में खुश है, यह है कि इंटरफेस को भाषा में बदल दिया जाता है - Zope.Interfaces।

C ++ के लिए, Google "डायमंड पदानुक्रम C ++" और उस कुरूपता को निहारें जो आपको कवर करने वाली है। C ++ पेशेवरों को पता है कि एकाधिक वंशानुक्रम का उपयोग कैसे करना है। हर कोई आमतौर पर सिर्फ यह जानने के बिना खेल रहा है कि परिणाम क्या होंगे। एक और बात जो यह बताती है कि इंटरफेस कितने उपयोगी हैं, यह तथ्य है कि कई मामलों में एक वर्ग को अपने माता-पिता के व्यवहार को पूरी तरह से ओवरराइड करने की आवश्यकता हो सकती है। ऐसे मामलों में, माता-पिता का कार्यान्वयन अनावश्यक है और केवल माता-पिता के निजी चर के लिए मेमोरी के साथ बच्चे की कक्षा पर बोझ डालते हैं, जो कि सी # उम्र में कोई फर्क नहीं पड़ता, लेकिन जब आप एम्बेडेड प्रोग्रामिंग करते हैं तो यह मायने रखता है। यदि आप एक इंटरफ़ेस का उपयोग करते हैं, तो यह समस्या कुछ भी नहीं है।

अंत में, इंटरफेस, मेरी राय में, ओओपी का एक अनिवार्य हिस्सा है, क्योंकि वे एक अनुबंध लागू करते हैं। मल्टीपल इनहेरिटेंस सीमित मामलों में उपयोगी है, और आमतौर पर केवल उन लोगों के लिए जो इसका उपयोग करना जानते हैं। इसलिए, यदि आप एक शुरुआत कर रहे हैं, तो आप एक हैं जो कई विरासत की कमी के द्वारा इलाज किया जाता है - यह आपको गलती नहीं करने का एक बेहतर मौका देता है

इसके अलावा, ऐतिहासिक रूप से, इंटरफ़ेस के लिए विचार Microsoft के C # डिज़ाइन स्पेक्स की तुलना में बहुत पहले से निहित है। अधिकांश लोग C # को जावा (अधिकांश इंद्रियों में) का उन्नयन मानते हैं, और अनुमान लगाते हैं कि C # को जावा से इसका इंटरफेस कहां से मिला। प्रोटोकॉल एक ही अवधारणा के लिए एक पुराना शब्द है, और यह .NET की तुलना में पुराना है।

अद्यतन: अब मैं देखता हूं कि मैंने एक अलग प्रश्न का उत्तर दिया हो सकता है - एकाधिक वंशानुक्रम के बजाय इंटरफेस क्यों, लेकिन ऐसा लग रहा था कि आप जिस उत्तर को देख रहे थे। एक ओओ भाषा के अलावा कम से कम दो में से एक होना चाहिए, और अन्य उत्तरों ने आपके मूल प्रश्न को कवर किया है।


6

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

मैं इस बात से सहमत नहीं हूं कि मल्टीपल इनहेरिटेंस इंटरफेस होने से बेहतर है, इससे पहले कि हम यह बहस करने लगें कि मल्टीपल इनहेरिटेंस में दर्द का सेट है। बहुरूपता और कोड पुन: उपयोग को सक्षम करने के लिए इंटरफेस एक बुनियादी उपकरण है, किसी को और क्या चाहिए?


5

मैं व्यक्तिगत रूप से अमूर्त वर्ग से प्यार करता हूं और इसे एक इंटरफ़ेस से अधिक उपयोग करता हूं। मुख्य अंतर .NET इंटरफेस के साथ एकीकृत करने के साथ आता है, जैसे कि आईडीसोपॉली, IEnumerable और इतने पर ... और COM इंटरॉप के साथ। इसके अलावा, इंटरफ़ेस एक अमूर्त वर्ग की तुलना में लिखने के लिए थोड़ा कम प्रयास है, और एक वर्ग एक से अधिक इंटरफ़ेस को लागू कर सकता है, जबकि यह केवल एक वर्ग से विरासत में मिल सकता है।

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

हालाँकि, आप आम तौर पर एक इंटरफ़ेस का उपयोग करते हैं जब आप सुपर क्लास पर एक निश्चित डिज़ाइन को लागू नहीं करना चाहते हैं, जबकि आप एक अमूर्त वर्ग का उपयोग करने के लिए एक पुन: प्रयोज्य डिज़ाइन का उपयोग करेंगे जो कि पहले से ही लागू है।

मैंने System.ComponentModel नाम स्थान का उपयोग करके प्लगइन वातावरण लिखने के साथ बड़े पैमाने पर इंटरफेस का उपयोग किया है। वे काफी काम आते हैं।


1
बहुत अच्छी तरह से डाल दिया! मुझे लगता है कि आप अमूर्त कक्षाओं पर मेरे लेख को पसंद करेंगे। अमूर्तता सब कुछ है
स्टीवन ज्यूरी

5

मैं कह सकता हूं कि मैं इससे संबंधित हूं। जब मैंने पहली बार OO और C # के बारे में सीखना शुरू किया तो मुझे भी इंटरफेसेस नहीं मिले। ठीक है। हमें बस कुछ ऐसा करने की आवश्यकता है जो आपको इंटरफेस की उपयुक्तता की सराहना करे।

मुझे दो तरीकों की कोशिश करते हैं। और सामान्यीकरण के लिए मुझे क्षमा करें।

1 आजमाएं

कहते हैं कि आप एक देशी अंग्रेजी वक्ता हैं। आप दूसरे देश में जाते हैं जहां अंग्रेजी मूल भाषा नहीं है। आप को मदद की आवश्यकता है। आपको किसी ऐसे व्यक्ति की जरूरत है जो आपकी मदद कर सके।

क्या आप पूछते हैं: "अरे, क्या आप संयुक्त राज्य में पैदा हुए थे?" यह विरासत है।

या आप पूछते हैं: "अरे, क्या आप अंग्रेजी बोलते हैं"? यह इंटरफ़ेस है।

यदि आप इसकी परवाह करते हैं कि यह क्या करता है, तो आप इंटरफेस में भरोसा कर सकते हैं। यदि आप परवाह करते हैं कि क्या है, तो आप विरासत पर भरोसा करते हैं।

विरासत पर भरोसा करना ठीक है। यदि आपको किसी ऐसे व्यक्ति की आवश्यकता है जो अंग्रेजी बोलता है, चाय पसंद करता है और फुटबॉल पसंद करता है, तो आप बेहतर तरीके से एक ब्रिट के लिए पूछ रहे हैं। :)

2 की कोशिश करो

ठीक है, चलो एक और उदाहरण की कोशिश करते हैं।

आप विभिन्न डेटाबेस का उपयोग करते हैं और आपको उनके साथ काम करने के लिए अमूर्त कक्षाओं को लागू करने की आवश्यकता होती है। आप अपनी कक्षा को डीबी विक्रेता से कुछ कक्षा में पास करेंगे।

public abstract class SuperDatabaseHelper
{
   void Connect (string User, string Password)
}

public abstract class HiperDatabaseHelper
{
   void Connect (string Password, string User)
}

एकाधिक वंशानुक्रम, आप कहते हैं? उपरोक्त मामले के साथ कोशिश करें। आप नहीं कर सकते। कंपाइलर को पता नहीं चलेगा कि आप किस कनेक्ट विधि को कॉल करने का प्रयास कर रहे हैं।

interface ISuperDatabaseHelper
{
  void Connect (string User, string Password)
}

interface IHiperDatabaseHelper
{
   void Connect (string Password, string User)
}

अब, कुछ ऐसा है जिससे हम काम कर सकते हैं - कम से कम C # में - जहाँ हम इंटरफेस को स्पष्ट रूप से लागू कर सकते हैं।

public class MyDatabaseHelper : ISuperDatabaseHelper, IHiperDatabaseHelper
{
   IHiperDataBaseHelper.Connect(string Password, string User)
   {
      //
   }

   ISuperDataBaseHelper.Connect(string User, string Password)
   {
      //
   }

}

निष्कर्ष

उदाहरण सबसे अच्छे नहीं हैं, लेकिन मुझे लगता है कि यह इस बिंदु पर पहुंच जाता है।

जब आप उनकी आवश्यकता महसूस करेंगे तो आप केवल "इंटरफेस" प्राप्त करेंगे। जब तक आप सोचेंगे कि वे आपके लिए नहीं हैं।


पहली कोशिश वह है जिसने मेरा वोट दिया।
ओसुंदबलाड

1
मैं अब से पूरी तरह से अमेरिकी बनाम अंग्रेजी अध्यक्ष सादृश्य का उपयोग कर रहा हूं। यह शानदार है।
ब्रायन बोएचर

सरल तरीके से समझाया गया! बहुत खुबस।
अनिल खान

4

2 प्रमुख कारण हैं:

  1. एकाधिक वंशानुक्रम की कमी। आप एक आधार वर्ग से विरासत में प्राप्त कर सकते हैं और किसी भी संख्या में इंटरफेस को लागू कर सकते हैं। .NET में कई उत्तराधिकारियों को "करने" का एकमात्र तरीका है।
  2. COM इंटरऑपरेबिलिटी। कुछ भी है कि "पुराने" प्रौद्योगिकियों द्वारा उपयोग करने की आवश्यकता होगी इंटरफेस को परिभाषित करने की आवश्यकता होगी।

बिंदु 1 निश्चित रूप से कारण और कारण है जो स्वयं Microsoft डेवलपर्स द्वारा विकसित किया गया है
पंकज उपाध्याय

1
@ पंकजा वास्तव में, उन्होंने जावा से इंटरफ़ेस विचार लिया (जैसे सी # के फीचर्स का एक अच्छा हिस्सा)।
ओलिवर वीलर

3

इंटरफेस का उपयोग एक प्रणाली को डिकूप्टेड रहने में मदद करता है और इस प्रकार रिफ्लेक्टर, परिवर्तन और पुन: प्रवाह को आसान बनाता है। यह ऑब्जेक्ट-ओरिएंटेड रूढ़िवादी के लिए एक बहुत ही मुख्य अवधारणा है और मैंने पहली बार इसके बारे में सीखा जब C ++ गुरुओं ने "शुद्ध अमूर्त वर्ग" बनाया जो इंटरफेस के काफी बराबर हैं।


Decoupling महत्वपूर्ण है क्योंकि यह एक सिस्टम के विभिन्न घटकों को एक दूसरे से स्वतंत्र रखता है। यह भी एक घटक में बड़े प्रभाव परिवर्तन अन्य घटकों के लिए बाहर लहर नहीं है। अपनी उपयोगिता कंपनी (वोल्टेज निर्दिष्ट करने और प्लग के भौतिक पिन और प्रारूप) के लिए एक इंटरफ़ेस के रूप में बिजली के प्लग के बारे में सोचें। इस इंटरफ़ेस के लिए धन्यवाद, उपयोगिता पूरी तरह से उनके बिजली उत्पादन का तरीका बदल सकती है (जैसे कि सौर प्रौद्योगिकी का उपयोग करें), फिर भी कोई भी उपकरण अकेले परिवर्तन को नोटिस नहीं करेगा।
१२:२५ पर चमत्कारिक

3

खुद से इंटरफेस बहुत उपयोगी नहीं हैं। लेकिन जब ठोस वर्गों द्वारा लागू किया जाता है तो आप देखते हैं कि यह आपको एक या अधिक कार्यान्वयन करने की सुविधा देता है। बोनस यह है कि इंटरफ़ेस का उपयोग करने वाली वस्तु को यह जानने की आवश्यकता नहीं है कि वास्तविक कार्यान्वयन का विवरण कैसे जाता है - जिसे एन्कैप्सुलेशन कहा जाता है।


2

वे ज्यादातर कोड पुन: प्रयोज्य के लिए उपयोग किए जाते हैं। यदि आप इंटरफ़ेस पर कोड करते हैं, तो आप एक अलग वर्ग का उपयोग कर सकते हैं जो उस इंटरफ़ेस से विरासत में मिलता है और सब कुछ नहीं तोड़ता है।

इसके अलावा वे वेबसर्विसेज में बहुत उपयोगी होते हैं जहाँ आप क्लाइंट को यह बताना चाहते हैं कि एक क्लास क्या करता है (इसलिए वे इसका उपभोग कर सकते हैं) लेकिन न ही उन्हें वास्तविक कोड देना चाहते हैं।


2

एक युवा प्रोग्रामर / डेवलपर के रूप में, सिर्फ C # सीखने से आप इंटरफ़ेस की उपयोगिता नहीं देख सकते हैं, क्योंकि आप अपनी कक्षाओं का उपयोग करके अपने कोड लिख सकते हैं और कोड ठीक काम करता है, लेकिन वास्तविक जीवन परिदृश्य में, एक स्केलेबल, मजबूत और बनाए रखने योग्य एप्लिकेशन का उपयोग करना शामिल है कुछ वास्तुशिल्प और पैटर्न, जिन्हें केवल इंटरफ़ेस का उपयोग करके संभव बनाया जा सकता है, उदाहरण निर्भरता इंजेक्शन में है।


1

एक वास्तविक दुनिया कार्यान्वयन:

आप इंटरफ़ेस प्रकार के रूप में एक वस्तु डाल सकते हैं:

IHelper h = (IHelper)o;
h.HelperMethod();

आप एक इंटरफ़ेस की एक सूची बना सकते हैं

List<IHelper> HelperList = new List<IHelper>();

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


0

इंटरफेसेस कुछ प्रकार के संदेशों को समझने के लिए (और सदस्यता लेने के लिए) सिस्टम को प्रदान करने के लिए कक्षाओं के लिए एक तंत्र प्रदान करके प्लगइन-शैली प्रतिरूपकता के लिए उधार देते हैं। मैं विस्तृत हूँ।

अपने आवेदन में, आप यह तय करते हैं कि जब भी कोई फ़ॉर्म लोड किया जाता है या पुनः लोड किया जाता है, तो आप चाहते हैं कि सभी चीजें जो इसे होस्ट करता है, उसे साफ़ कर दिया जाए। आप एक IClearइंटरफ़ेस परिभाषित करते हैं जो लागू करता है Clear। इसके अतिरिक्त, आप यह तय करते हैं कि जब भी उपयोगकर्ता सेव बटन को हिट करता है, तो फॉर्म को उसकी स्थिति को बनाए रखने का प्रयास करना चाहिए। इस प्रकार, जो कुछ भी पालन करता है वह ISaveअपनी स्थिति को बनाए रखने के लिए एक संदेश प्राप्त करता है । बेशक, व्यावहारिक रूप से, अधिकांश इंटरफेस कई संदेशों को संभालते हैं।

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

अधिकांश भाषाओं में इंटरफ़ेस द्वारा पालन की जाने वाली चीजों को क्वेरी करने के लिए तंत्र (जैसे LINQ ) होते हैं । यह आमतौर पर आपको सशर्त तर्क को खत्म करने में मदद करेगा क्योंकि आपको असंतुष्ट चीजें (जो एक ही विरासत श्रृंखला से आवश्यक नहीं हैं) को समान तरीके से व्यवहार करने के लिए नहीं बताना होगा (एक विशेष संदेश के अनुसार)। इसके बजाय, आप वह सब कुछ इकट्ठा करते हैं जो एक निश्चित संदेश (एक इंटरफ़ेस द्वारा पालन) को समझता है और संदेश को प्रकाशित करता है।

उदाहरण के लिए, आप प्रतिस्थापित कर सकते हैं ...

Me.PublishDate.Clear()
Me.Subject.Clear()
Me.Body.Clear()

...साथ में:

For Each ctl As IClear In Me.Controls.OfType(Of IClear)()
    ctl.Clear()
Next

जो प्रभावी रूप से बहुत कुछ लगता है:

सुनो सुनो, सुनो! क्या हर कोई क्लीयरिंग को समझता है, कृपया Clearअब!

इस तरह, हम प्रोग्राम को स्पष्ट रूप से प्रत्येक और हर बात को स्पष्ट करने से बच सकते हैं। और जब भविष्य में clearable आइटम जोड़े जाते हैं तो वे बस बिना किसी अतिरिक्त कोड के प्रतिक्रिया देते हैं।


0

निम्नलिखित छद्मकोश है:

class MyClass{

    private MyInterface = new MyInterfaceImplementationB();

    // Code using Thingy 

}

interface MyInterface{

    myMethod();

}

class MyInterfaceImplementationA{ myMethod(){ // method implementation A } }

class MyInterfaceImplementationB{ myMethod(){ // method implementation B } }

class MyInterfaceImplementationC{ myMethod(){ // method implementation C } }

अंतिम कक्षाएं पूरी तरह से अलग कार्यान्वयन हो सकती हैं।

जब तक एकाधिक वंशानुक्रम संभव नहीं होता है, वंशानुक्रम मूल वर्ग के कार्यान्वयन को लागू करता है जिससे चीजें अधिक कठोर हो जाती हैं। दूसरी ओर इंटरफेस के खिलाफ प्रोग्रामिंग आपके कोड या एक ढांचे को बेहद लचीला होने की अनुमति दे सकता है। यदि आप कभी ऐसे मामले में आते हैं जहाँ आप चाहते हैं कि आप एक विरासत श्रृंखला में कक्षाओं के आसपास स्वैप कर सकें, तो आप समझेंगे कि क्यों।

उदाहरण के लिए, एक फ्रेमवर्क जो एक रीडर प्रदान करता है जिसका मूल रूप से डिस्क से डेटा पढ़ने का इरादा है, उसी प्रकृति के कुछ करने के लिए फिर से लागू किया जा सकता है लेकिन पूरी तरह से अलग तरीके से। उदाहरण के लिए मोर्स कोड की व्याख्या करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.