2010-07-22 6 views
5

मैं के रूप मेंएक सार आधार वर्ग में अनुबंध को आंशिक रूप से कार्यान्वित कैसे करें?

public interface IX 
    { 
     void MethodA(); 
     void MethodB(); 
    } 

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

public abstract class XBase:IX 
    { 
     public void MethodA() 
     { 
      // Common behaviour implementation 
     } 

     public abstract void MethodB(); 
    } 

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

लेकिन यहां अमूर्त वर्ग में मैं 'सार्वजनिक सार शून्य विधि) ('; 'जोड़ता हूं। यह विधि बी अनुबंध की पुनरावृत्ति की तरह दिखता है।

कक्षा # सारणी इंटरफ़ेस कार्यान्वयन की अनुमति क्यों नहीं देती है? उपरोक्त इंटरफ़ेस में केवल दो विधियां हैं। मान लीजिए कि एक इंटरफ़ेस में 10 विधियां हैं और 5 सामान्य कार्यक्षमता हैं और 5 नहीं हैं, हमें 5 विधियों को जोड़ने के लिए मजबूर होना जरूरी है जो अमूर्त वर्ग में आम नहीं हैं?

+0

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

+0

@ कैमरॉन: असल में मुझे लगता है कि यह एक बहुत अच्छा दृष्टिकोण है। आप सैद्धांतिक रूप से कई अलग-अलग सार आधार वर्गों को प्राप्त कर सकते हैं जो सभी कार्यान्वयन के लिए कुछ मौलिक रूप से अलग दृष्टिकोण के माध्यम से एक ही इंटरफ़ेस को लागू करते हैं। –

उत्तर

8

क्योंकि सी # भाषा विनिर्देश ऐसा कहता है। अध्याय 13.4.7:

एक गैर-सारणी वर्ग की तरह, एक अमूर्त वर्ग को वर्ग की बेस क्लास सूची में सूचीबद्ध इंटरफेस के सभी सदस्यों के कार्यान्वयन प्रदान करना होगा।

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

+1

हंस मैं समझता हूं कि यह लागू है, लेकिन जानना उत्सुक है कि भाषा इसे क्यों लागू करती है? उत्तर के लिए धन्यवाद – RAM

+3

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

1

इसका समर्थन करने का कारण यह नहीं है क्योंकि आपका सुपरक्लास अनुबंध को पूरा नहीं करता है। एक सार वर्ग के लिए अपने उप-वर्गों पर कार्यान्वयन को मजबूर करने का एकमात्र तरीका अमूर्त तरीकों को परिभाषित करना है।

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

प्रश्न होना चाहिए, यह आपके सुपरक्लास पर 5 अमूर्त तरीकों के साथ समस्या क्यों होगी?

+1

मुझे लगता है कि इस स्थिति में रैम क्या हो रहा है संकलक स्वचालित रूप से अमूर्त इंटरफेस विधि हस्ताक्षर उत्पन्न कर सकता है। –

+1

@ सैम - यह हो सकता है, लेकिन यह सबक्लास को लागू करने वाले किसी और के लिए अस्पष्ट रूप से भ्रमित होगा। वे सुपरक्लास पर इंटरफेस को जरूरी नहीं देख सकते हैं, तो उन्हें कैसे पता चलेगा कि उन्हें क्या लागू करना है? – pdr

+1

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

0

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

एक घर दृष्टिकोण पर इस कोशिश नहीं करते कृपया के रूप में, तुम कर सकते हो की तरह

class Derived : Base, IFoo 
{ 
    public void MethodB() 
    { 
    } 
} 

abstract class Base 
{ 
    public Base() 
    { 
     if (!(this is IFoo)) 
      throw new InvalidOperationException("must implement IFoo"); 
    } 

    public void MethodA() { } 
} 

interface IFoo 
{ 
    void MethodA(); 
    void MethodB(); 
} 

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

0

कैसे आप एक स्थिति है जहाँ आप

interface IFoo { 
    void MethodA(); 
    void MethodB(); 
} 
abstract class Base: IFoo { 
    public void MethodA() {} 
    // MethodB gets implicitly generated 
} 
class Derived: Base { 
    public void MethodB() {} 
} 

आप तो ऐसा कर सकता है है संभाल होगा:

Base myBase = ... 
myBase.MethodB(); 

ठीक है, तुम कर सकते थे, MethodB के बाद से निहित है। लेकिन क्या होगा यदि आप बाद में Base कक्षा से इंटरफ़ेस IFoo को निकालने का निर्णय लेंगे? आपने अभी Base के अनुबंध को तोड़ दिया है .. समाधान होगा कि उत्पन्न विधियां स्पष्ट इंटरफ़ेस कार्यान्वयन होंगी, लेकिन इससे एक और प्रकार का दर्द आता है।

0

आप विधि घोषणा में 'आभासी' करने के लिए 'सार' से स्विच और एक अभिकथन प्रदान कर सकते हैं:

public abstract void MethodB(); 

public virtual void MethodB() 
{ 
    Contract.Require(your condition); 
} 
0

मैं सार वर्ग या इंटरफ़ेस नहीं लगता कि क्या कर रहा है हो जाता है सॉलिड सिद्धांतों के अनुसार आपके परिदृश्य में कोई अन्याय (विशेष रूप से: इंटरफ़ेस पृथक्करण सिद्धांत): https://msdn.microsoft.com/en-us/library/dn178470(v=pandp.30).aspx

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

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