2009-07-17 19 views
7

मैं इस स्थिति यह है कि जब AbstractMethod विधि ImplementClass से शुरू हो जाती है मैं लागू करने के लिए MustBeCalled कि AbstractClass में विधि शुरू हो जाती है चाहते हैं। मैं पहले कभी इस स्थिति में नहीं आया है। धन्यवाद!ओवरराइडिंग विधि लागू होने पर विधि कॉल (बेस क्लास में) को कैसे लागू किया जाए?

public abstract class AbstractClass 
{ 
    public abstract void AbstractMethod(); 

    public void MustBeCalled() 
    { 
     //this must be called when AbstractMethod is invoked 
    } 
} 

public class ImplementClass : AbstractClass 
{ 
    public override void AbstractMethod() 
    { 
     //when called, base.MustBeCalled() must be called. 
     //how can i enforce this? 
    } 
} 
+0

जब बच्चे वर्ग द्वारा AbstractClass.AbstractMethod का आह्वान किया जाता है तो एक सार को AbClClass.MustBeCalled का आह्वान करने के लिए उठाया जाता है। लेकिन फिर भी यह सुनिश्चित नहीं है कि इसे कैसे किया जाए। – Jeff

उत्तर

8

एक विकल्प सार वर्ग के लिए किया जाएगा इस तरह से बुला कर। अन्यथा, एक निश्चित तरीके से एक विधि को लागू करने के लिए विरासत वर्ग की आवश्यकता के लिए सी # में कोई रास्ता नहीं है।

public abstract class AbstractClass 
{ 
    public void PerformThisFunction() 
    { 
     MustBeCalled(); 
     AbstractMethod(); 
    } 

    public void MustBeCalled() 
    { 
     //this must be called when AbstractMethod is invoked 
    } 

    //could also be public if desired 
    protected abstract void AbstractMethod(); 
} 

public class ImplementClass : AbstractClass 
{ 
    protected override void AbstractMethod() 
    { 
     //when called, base.MustBeCalled() must be called. 
     //how can i enforce this? 
    } 
} 

इस सार कक्षा में वांछित सार्वजनिक संपर्क वाले विधि बनाता करने से,, पर कैसे और किस क्रम में बातें कहा जाता है सार वर्ग देने, जबकि अभी भी ठोस वर्ग आवश्यक सुविधा प्रदान करने की इजाजत दी।

+0

*** धन्यवाद। *** – Jeff

+0

मैंने इस पैटर्न का भी उपयोग किया है। मेरा मानना ​​है कि यह वास्तव में चार डिजाइन पैटर्न की गिरोह में से एक है, लेकिन मेरी पुष्टि करने के लिए यहां मेरी पुस्तक नहीं है। – MedicineMan

+0

बेस.AbstractMethod() कहलाते समय ईवेंट को बढ़ाने के बारे में कैसे? – Jeff

-1

आप कार्यान्वयन कक्षा के सार तत्व() में विधि क्यों नहीं कह सकते हैं?

6

कैसे

के बारे में
public abstract class AbstractClass 
{ 
    public void AbstractMethod() 
    { 
     MustBeCalled(); 
     InternalAbstractMethod(); 
    } 

    protected abstract void InternalAbstractMethod(); 

    public void MustBeCalled() 
    { 
     //this must be called when AbstractMethod is invoked 
    } 
} 

public class ImplementClass : AbstractClass 
{ 
    protected override void InternalAbstractMethod() 
    { 
     //when called, base.MustBeCalled() must be called. 
     //how can i enforce this? 
    } 
} 
+1

इस कार्यान्वयन में, मुझे नहीं लगता कि आपने उपयोगकर्ता को MustBeCalled को कॉल करने के लिए मजबूर कर दिया है। जब AbstractClass.AbstractMethod कहा जाता है, ImplementClass.AbstractMethod कहा जाता है, लेकिन MustBeCalled नहीं है। मेरा मानना ​​है कि yshuditelu का बेहतर समाधान – MedicineMan

0

एक बात पूर्ववर्ती समाधान पर ध्यान न दें कि ImplementClass MethodToBeCalled को फिर से परिभाषित कर सकते हैं और MustBeCalled फोन नहीं है -

public abstract class AbstractClass 
{ 
    public abstract void AbstractMethod(); 

    private void MustBeCalled() 
    { 
     //will be invoked by MethodToBeCalled(); 
     Console.WriteLine("AbstractClass.MustBeCalled"); 
    } 

    public void MethodToBeCalled() 
    { 
     MustBeCalled(); 
     AbstractMethod(); 
    } 
} 

public class ImplementClass : AbstractClass 
{ 
    public override void AbstractMethod() 
    { 
     Console.WriteLine("ImplementClass.InternalAbstractMethod"); 
    } 

    public new void MethodToBeCalled() { 
     AbstractMethod(); 
    } 
} 

अगर केवल सी # अनुमति गैर अधिरोहित तरीकों सील किया जा करने के लिए - जावा के अंतिम कीवर्ड की तरह!

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

namespace Something 
{ 

    public sealed class OuterClass 
    { 
     private AbstractInnerClass inner; 

     public OuterClass(AbstractInnerClass inner) 
     { 
      this.inner = inner; 
     } 

     public void MethodToBeCalled() 
     { 
      MustBeCalled(); 
      inner.CalledByOuter(); 
     } 

     public void MustBeCalled() 
     { 
      //this must be called when AbstractMethod is invoked 
      System.Console.WriteLine("OuterClass.MustBeCalled"); 
     } 
    } 

    public abstract class AbstractInnerClass 
    { 
     internal void CalledByOuter() 
     { 
      AbstractMethod(); 
     } 

     protected abstract void AbstractMethod(); 
    } 
} 

public class ImplementInnerClass : Something.AbstractInnerClass 
{ 
    protected override void AbstractMethod() 
    { 
     //when called, base.MustBeCalled() must be called. 
     //how can i enforce this? 
     System.Console.WriteLine("ImplementInnerClass.AbstractMethod"); 
    } 

    public new void CalledByOuter() 
    { 
     System.Console.WriteLine("doesn't work"); 
    } 
} 
+0

तथ्य यह है कि एक व्युत्पन्न वर्ग छाया कर सकता है MethodToBeCalled कोड के लिए समस्या उत्पन्न नहीं करेगा जो व्युत्पन्न-वर्ग ऑब्जेक्ट को बेस-क्लास के रूप में उपयोग करता है। मुझे लगता है कि अगर "निजी अधिभार" तरीकों की अनुमति है तो विधि पदानुक्रमों में सुधार किया जा सकता है; मुझे नहीं पता कि कोई तकनीकी कारण नहीं है या नहीं। एक निजी अधिभार विधि केवल बेस क्लास से या एक व्युत्पन्न वर्ग के भीतर से उसी विधि के ओवरराइड से ही बुलाया जा सकता है। बेस-क्लास कॉल के भीतर सबसे अधिक व्युत्पन्न संस्करण में छोड़कर आधार कार्यान्वयन में कोड को कॉल करना असंभव होगा। – supercat

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