C # में, क्या एक क्लास दूसरी क्लास और एक इंटरफ़ेस से इनहेरिट कर सकती है?


130

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

इस प्रश्न को जोड़ने के लिए: यदि GenericDevice अलग प्रोजेक्ट में है, तो क्या मैं IOurDevices इंटरफ़ेस को उस प्रोजेक्ट में रख सकता हूँ और फिर USBDevice क्लास को इंटरफ़ेस को लागू कर सकता हूँ अगर मैं पहली परियोजना का संदर्भ जोड़ूँ? क्योंकि सिर्फ एक परियोजना का संदर्भ लेना चाहते हैं और फिर डिवाइस क्या है, इसके आधार पर विभिन्न इंटरफेस को लागू करें।

class GenericDevice
{
   private string _connectionState;
   public connectionState
   {
      get{return _connectionState; }
      set{ _connectionState = value;}
   }
}

interface IOurDevices
{
   void connectToDevice();
   void DisconnectDevice();
   void GetFirmwareVersion();
}

class USBDevice : IOurDevices : GenericDevice
{
   //here I would define the methods in the interface
   //like this...
   void connectToDevice()
   {
       connectionState = "connected";
   }
}

//so that in my main program I can do this...

class myProgram
{
   main()
   {
      USBDevice myUSB = new USBDevice();
      myUSB.ConnectToDevice;
   }
}

5
आपके भविष्य के संदर्भ के लिए, C # विनिर्देश के अनुभाग 10.1.4 में सटीक वर्णन किया गया है कि एक वर्ग को कैसे घोषित किया जाए जिसमें कई आधार प्रकार हों।
एरिक लिपर्ट

@ एरिक लिपर्ट: क्या आप मुझे इस मामले के बारे में समझने में मदद कर सकते हैं कि क्या यह सही तरीका है और भविष्य में उपलब्ध होगा?
गुल एमडी इरशाद

जवाबों:


246

हाँ। प्रयत्न:

class USBDevice : GenericDevice, IOurDevice

नोट: इंटरफ़ेस नामों की सूची से पहले आधार वर्ग आना चाहिए।

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


1
हाँ यह काम करता है! मैंने ऐसा क्यों नहीं सोचा! और नीचे टिप्पणी करने के लिए। मुझे उस पर क्लीयर करने के लिए धन्यवाद (क्लासेस
इंटरहेट

1
@ जोर्डन, यह भी ध्यान दें कि प्रारंभिक वर्ग (@ मेहरदाद के उदाहरण) के बाद बेस क्लास और विरासत में मिली इंटरफेस की सूची कोमा से अलग कर दिया गया है।
जेएमडी

1
थोड़ा विस्तार करने के लिए: यदि आपका बेस क्लास इंटरफ़ेस लागू करता है तो आपका व्युत्पन्न वर्ग स्वचालित रूप से उस इंटरफ़ेस को लागू करता है - बिना भी USBDevice : IOurDevice। स्पष्ट रूप से कार्यान्वयन को जोड़ने से आधार वर्ग प्रभावित नहीं होता है, लेकिन यह इंटरफ़ेस पर जोर देने में मदद कर सकता है।
STW

1
@ डेविड, जब आप गलत नहीं हैं, तो यह शब्दावली नहीं थी जो @ जॉर्डन के कोड को काम करने से रोक रही थी। यह गलत सिंटैक्स था।
जेएमडी

2
+1 भी एक प्रश्न को क्लीयर करने के लिए जो मैं बेस और इंटरफेस दोनों में समान सदस्यों के बारे में पूछना चाहता था।
रिगार्ड्ट स्टेन

21

नहीं, बिल्कुल नहीं। लेकिन यह एक वर्ग से विरासत में मिल सकता है और एक या एक से अधिक इंटरफेस को लागू कर सकता है।

इस तरह की अवधारणाओं पर चर्चा करते समय स्पष्ट शब्दावली महत्वपूर्ण है। जिन चीजों में से एक को आप देखेंगे, वह है कि जॉन स्कीट का लेखन, उदाहरण के लिए, यहाँ और प्रिंट में, यह है कि वह हमेशा उसी तरह से सटीक होता है जिस तरह से वह चीजों को डिक्रिप्ट करता है।


8
या एरिक लिपर्ट, जिनका लेखन बहुत सटीक है।
मथियास

21

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

.NET बहु-उत्तराधिकार का समर्थन नहीं करता है, इसलिए शर्तों को सीधे रखने से संचार में मदद मिल सकती है। एक वर्ग एक सुपरक्लास से विरासत में मिल सकता है और अपनी इच्छानुसार कई इंटरफेस लागू कर सकता है।


एरिक की टिप्पणी के जवाब में ... मैंने एक अन्य डेवलपर के साथ चर्चा की कि क्या "विरासत", "कार्यान्वयन", "आवश्यकता", या "एक साथ घोषणाओं के साथ" इंटरफेस लाने के बारे में:

public interface ITwo : IOne

तकनीकी उत्तर यह है कि कुछ कारणों से ITwoविरासत में मिला है IOne:

  • इंटरफेस का कार्यान्वयन कभी नहीं होता है, इसलिए यह तर्क देना कि ITwo लागू IOne करना गलत है
  • ITwoइनहेरिट करने के IOneतरीके, अगर MethodOne()मौजूद हैं, IOneतो यह भी आकस्मिक है ITwo। यानी: ((ITwo)someObject).MethodOne())वैध है, भले ही ITwoस्पष्ट रूप से इसके लिए परिभाषा नहीं हैMethodOne()
  • ... क्योंकि रनटाइम ऐसा कहता है! typeof(IOne).IsAssignableFrom(typeof(ITwo))रिटर्नtrue

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


3
हालांकि, दुर्भाग्य से, इंटरफेस अन्य इंटरफेस विरासत में मिला । मुझे लगता है कि शब्दों का चयन दुर्भाग्यपूर्ण है, लेकिन हम इसके साथ फंस गए हैं। मैं अन्य इंटरफेस की आवश्यकता के रूप में इंटरफेस के बारे में सोचना पसंद करता हूं । यही है, जब आप कहते हैं "इंटरफ़ेस IFoo: IBar" इसका मतलब है कि "IFoo के एक कार्यान्वयनकर्ता को भी IBAR को लागू करना आवश्यक है"।
एरिक लिपर्ट

@ मैं मानता हूं कि यह एक अस्पष्ट शब्द है और कुछ समय पहले एक सहकर्मी के साथ इस पर बहस हुई थी। अंत में हमने निर्णय लिया कि "ITwo को IOne विरासत में मिला है"। मैं अपने उत्तर को कुछ छोटे कारणों से अपडेट करूंगा (सिर्फ इसलिए कि वे एक टिप्पणी में स्पष्ट रूप से फिट नहीं होंगे)।
STW

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

एक और शब्द मुझे पसंद है "विस्तार"। तो आप "इंटरफ़ेस IFoo: IBar" पढ़ सकते हैं, जिसका अर्थ है कि IFoo IBar की आवश्यकताओं का विस्तार करता है।
जासन

1
@ जोआन: आप सही हैं कि कक्षाएं लागू होती हैं (और इनहेरिट नहीं कर सकती) इंटरफेस। एरिक का कहना है कि इंटरफेस अन्य इंटरफेस को विरासत में दे सकता है - जो कि पचाने के लिए कुछ हद तक कठिन हो सकता है क्योंकि इंटरफेस कार्यान्वयन के बजाय केवल "विनिर्देश" हैं।
एसटीडब्ल्यू

1

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


इसे सभी मामलों में सार्वजनिक नहीं होना चाहिए। बस सुलभ है। उदाहरण के लिए class ContainsAll { private interface INested { /* ... */ } private class MyExample : INested { /* ... */ } }, MyExampleवर्ग एक नेस्टेड निजी इंटरफ़ेस लागू करता है। अन्य उदाहरणों में, नेस्टेड इंटरफ़ेस (और युक्त वर्ग) हो सकता है internal। यह सब इस बात पर निर्भर करता है कि उन्हें किसका उपयोग करना है और किससे परेशान होना है।
जेपी स्टिग नीलसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.