2009-07-07 14 views
6

मैं बेस क्लास में एक फ़ंक्शन को कार्यान्वित करना चाहता हूं लेकिन मैं यह भी चाहता हूं कि व्युत्पन्न कक्षा हर बार पर इसे ओवरराइड किया जाए। तो यह "अमूर्त कार्य लेकिन शरीर के साथ" की तरह है।विधि को ओवरराइड किया जाना चाहिए लेकिन सार नहीं है?

मैं क्या देख रहा हूं? क्या मैं सही चीज़ ढूंढ रहा हूं?

उत्तर

14

आधार स्तरीय कुछ कहने के लिए है, लेकिन आप चाहते हैं कि उसे ओवरराइड "हर बार", तो मैं तरीकों की एक जोड़ी के लिए होता है, तो:

public void DoSomething() { 
    //things to do before 
    DoSomethingCore(); 
    //things to do after 
} 
protected abstract void DoSomethingCore(); 
+3

और आप टेम्पलेट विधि पैटर्न (या अन्यथा आप ब्रेवटी के लिए शूटिंग कर रहे हैं) का उल्लेख करने के लिए हो सकता है –

+0

DoSomething विधि से पहले "वर्चुअल" कीवर्ड के बारे में क्या? – Kamarey

+1

@ कामरेय Do Doomomething विधि वर्चुअल नहीं है: यह DoSomethingCore विधि है कि उप-वर्गों को ओवरराइट/कार्यान्वित करने की अपेक्षा की जाती है। – ChrisW

1

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

public virtual YourMethod() { 
    // your base class code here 
} 

और फिर एक अलग वर्ग में अधिभावी विधि:

public override YourMethod() { 
    // code to do before the base call 
    base.YourMethod(); 
    // code to do after the base call 
} 
3

अपने आधार वर्ग विधि में कुछ करता है, लेकिन आप यह सुनिश्चित करें कि हर उपवर्ग कुछ को लागू करने के लिए मजबूर है बनाना चाहते हैं विधि का हिस्सा, तो आप मार्क ग्रेवेल के जवाब में वर्णित Template Method pattern चाहते हैं।

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

public abstract class FooBase { 
    public abstract void DoStuff(); 
} 

public sealed class FooImpl : FooBase { 
    public override void DoStuff { 
     //default widget-munging code 
    } 
} 

अब किसी भी वर्ग है जो FooBase से विरासत DoStuff() लागू करने के लिए है, लेकिन आप एक डिफ़ॉल्ट कार्यान्वयन FooImpl जहाँ से उपवर्गों के वारिस नहीं हो सकता है।

आप एक अलग वर्ग के लिए विधि को लागू करने की ज़िम्मेदारी भी लेना पसंद कर सकते हैं, जो कि इसके कन्स्ट्रक्टर में बेस क्लास को पास किया जाता है। इसे Strategy pattern कहा जाता है।

public sealed class Foo { 
    private IFooStrategy _strategy; 
    public Foo(IStrategy strategy) { 
     _strategy = strategy; 
    } 
    void DoStuff() { 
     _strategy.DoStuff(); 
    } 
    public static IFooStrategy DefaultStrategy { 
     //return singleton instance of the default strategy 
    } 
} 

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

new Foo(Foo.DefaultStrategy); 

या

new Foo(new DifferentStrategy()); 
1

अपने आधार कार्यान्वयन की तरह लगता है के नाम से जाना कभी नहीं होगा। आप एक कार्यान्वयन क्यों प्रदान करना चाहते हैं कि कोई भी नहीं हो सकता है (उछाल वाले हुप्स के माध्यम से कूदना)

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