2009-11-06 15 views
45

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

मुझे आशा है कि यह (शायद लंबे समय तक के लिए) काफी स्पष्ट था लेकिन किसी को भी मुझे इस या तो पर कुछ सलाह दे सकते हैं अगर मैं इसे सही कर रहा हूँ या मैं कर रहा हूँ यह गलत तो कृपया मुझे बताएं।

धन्यवाद!

उत्तर

60

इंटरफ़ेस विरासत, एक उत्कृष्ट उपकरण है कि आप केवल यह है, जब इंटरफ़ेस बी इंटरफ़ेस एक के लिए सही मायने में substitutable है का उपयोग करना चाहिए सिर्फ शिथिल संबंधी व्यवहार एकत्र करने के लिए नहीं।

यह कहना मुश्किल है कि यह आपके विशिष्ट मामले के लिए उपयुक्त है, लेकिन सिद्धांत में अभ्यास में कुछ भी गलत नहीं है। आप इसे हर समय पहली दर एपीआई में देखते हैं। सिर्फ एक सामान्य उदाहरण लेने के लिए, नेट ढांचे से:

public interface ICollection<T> : IEnumerable<T>, IEnumerable 
+2

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

+0

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

2

IMO यह बिल्कुल सही दृष्टिकोण है, मैं इसके साथ किसी भी समस्या नहीं दिख रहा।

6

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

+0

अच्छी स्थिति और हाँ इस स्थिति में वे संबंधित हैं। – ajrawson

5

तकनीकी रूप से बोलते हुए, इंटरफेस एक-दूसरे से प्राप्त नहीं होते हैं। क्या वास्तव में होता है जब आप एक IFoo कि IBar से विरासत बनाने के लिए, तुम कह रहे हो कि किसी भी वर्ग कि IFoo लागू करता भी IBar को लागू करना चाहिए।

interface IBar 
{ 
    void DoBar(); 
} 

interface IFoo : IBar 
{ 
    void DoFoo(); 
} 

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

+3

यहां तक ​​कि आपके द्वारा वर्णित व्यवहार को भी दिया गया है (फिल हैक के हालिया कॉलम में उत्कृष्ट विवरण में वर्णित है, http://haacked.com/archive/2009/11/10/interface-inheritance-esoterica.aspx), मुझे लगता है कि यह अनावश्यक भ्रमित है कहने के लिए 'सी # संदर्भ में अंतरफलक एक दूसरे से उत्तराधिकारी नहीं होते हैं' जब सी # संदर्भ दस्तावेज भी उस शब्दावली का उपयोग करता है, जैसा कि "एक इंटरफ़ेस एक या अधिक बेस इंटरफेस से प्राप्त हो सकता है।" (http://msdn.microsoft.com/en-us/library/87d83y5b%28VS.80%29.aspx) मैं बस यह कहना पसंद करूंगा कि, सी # में, विरासत सदस्यों को प्रतिबिंबित करते समय इंटरफ़ेस विरासत वर्ग विरासत से भिन्न व्यवहार करता है । –

+1

पर्याप्त मेला। मुझे लगता है कि यह "विरासत" को परिभाषित करने के तरीके पर निर्भर करता है। निश्चित रूप से सी # वाक्यविन्यास वही है चाहे वह कक्षाएं या इंटरफेस हों। लेकिन यदि आप माता-पिता के सदस्यों को विरासत के बारे में सोचते हैं, तो जब आप इंटरफेस के बारे में बात कर रहे हों तो आपका मानसिक मॉडल वास्तविकता से मेल नहीं खाता है। –

1

मुझे लगता है कि डेटाबेस हमेशा एक शानदार तरीका इंटरफेस प्रदर्शित करने के लिए प्रदान करते हैं, तो पर विचार करता है, तो एक अंतरफलक निम्नलिखित में एक और इंटरफ़ेस के वारिस चाहिए,

IMySqlDatabase : IDatabase 
MySqlDatabase : IMySqlDatabase 

IMsSqlDatabase : IDatabase 
MsSqlDatabase : IMsSqlDatabase 

एक MySqlDatabase एक IMySqlDatabase है और एक IMySqlDatabase एक IDatabase है।

अब यदि आपको अपने आईडीटाबेस इंटरफ़ेस में परिवर्तन करने की आवश्यकता है तो यह पोते-पोते (कंक्रीट डेटाबेस कक्षाएं) लाभ काट सकते हैं, लेकिन आपको MySQL और MsSQL (या शायद और भी अधिक डीबीएमएस 'इंटरफेस) का विस्तार नहीं करना पड़ेगा।आपके मध्य व्यक्ति (IMSSqlDatabase) में एक ही समय में आपके पास अभी भी इंटरफ़ेस सुविधाएं हो सकती हैं जो एक MySQL या Oracle DB का समर्थन नहीं करेगा।

13

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

चलिए एक उदाहरण देखें;

public interface IScanner 
{ 
    void Scan(); 
} 

public interface IPrinter 
{ 
    void Print(); 
} 

प्रिंटर और स्कैनर अक्सर अलग वस्तुओं रहे हैं, अपने स्वयं के कार्यक्षमता हालांकि इन दोनों उपकरणों अक्सर एक ही डिवाइस में जोड़ा जाता है के साथ प्रत्येक;

public interface IPhotocopier : IScanner, IPrinter 
{ 
    void Copy(); 
} 

यह भावना है कि IPhotocopier IScanner और IPrinter से विरासत चाहिए यह अब की अनुमति देता है के रूप में फोटोकॉपियर या तो एक स्कैनर या प्रिंटर (जो यह होता है) एक कॉपियर रूप में अपनी प्राथमिक रोल के अलावा के रूप में इस्तेमाल किया जा है।

अब एक और इंटरफ़ेस देखें;

public interface IBlender 
{ 
    void Blend(); 
} 

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

यदि आप अपना नया इंटरफ़ेस एक समझदार नाम नहीं दे सकते हैं तो यह संकेत दे सकता है कि आप इस उदाहरण में विरासत का उपयोग नहीं करना चाहेंगे।

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

संबंधित मुद्दे