सवाल सी # में 'अमूर्त ओवरराइड' का उपयोग क्या है?


जिज्ञासा से बाहर मैंने आधार वर्ग में एक अमूर्त विधि को ओवरराइड करने की कोशिश की, और क्रियान्वयन सार विधि को विधिबद्ध किया। नीचे के अनुसार:

public abstract class FirstAbstract
{
    public abstract void SomeMethod();
}

public abstract class SecondAbstract : FirstAbstract
{
    public abstract override void SomeMethod();
    //?? what sense does this make? no implementaion would anyway force the derived classes to implement abstract method?
}

जानना उत्सुक क्यों सी # कंपाइलर 'अमूर्त ओवरराइड' लिखने की अनुमति देता है। क्या यह अनावश्यक नहीं है? इस तरह कुछ करने के लिए एक संकलन समय त्रुटि होना चाहिए। क्या यह कुछ उपयोग-मामले में काम करता है?

आपकी रुचि के लिए धन्यवाद।


44
2018-01-18 05:03


मूल


मैंने इस सुविधा का उपयोग दो बार किया है। निश्चित रूप से मामलों का उपयोग कर रहे हैं। - ChaosPandion
इससे मदद मिलनी चाहिए: blogs.msdn.com/b/jmstall/archive/2005/08/07/... - VS1
कुछ ऐसा क्यों होना चाहिए जो संक्रामक समय त्रुटि के कारण केवल अनावश्यक है? - saus
@saus क्योंकि कुछ अनावश्यक चीजें मूर्खतापूर्ण हैं कि वे गलती या गलतफहमी का सुझाव देते हैं और इसलिए एक त्रुटि या कम से कम एक चेतावनी उचित है। public इंटरफ़ेस सदस्यों पर एक उदाहरण होगा। - Jon Hanna
मेरे पास एक केस केस था और यह शोध कर रहा था कि यह कैसे करें, जिसने मुझे इस सवाल का नेतृत्व किया। आपके प्रश्न ने मेरे प्रश्न का उत्तर दिया, धन्यवाद! - palswim


जवाब:


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

public class D
{
    public virtual void DoWork(int i)
    {
        // Original implementation.
    }
}

public abstract class E : D
{
    public abstract override void DoWork(int i);
}

public class F : E
{
    public override void DoWork(int i)
    {
        // New implementation.
    }
}

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


56
2018-01-18 05:08



अगर मैंने कुछ किया तो क्या होगा F ff = new F(); D dd = ff as D; dd.DoWork(0);? वह कॉल नहीं करेगा Dकार्यान्वयन? और यदि यह सच है, तो क्या मैं अंदर डाल सकता हूं Fकी DoWork(int i)कोड कुछ पसंद है D dd = this as D; dd.DoWork(i);? क्या वह कॉल करेगा Dकार्यान्वयन? - Blueriver
@ ब्लूवर किसी भी आभासी सदस्य के रूप में, यह वास्तविक वस्तु के कार्यान्वयन को बुलाएगा, इसलिए यह मामला कॉल करेगा Fकार्यान्वयन - Jon Hanna


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

public abstract class Base
{
    public abstract override string ToString();
}

यह कार्यान्वयन करने वालों के लिए एक स्पष्ट संकेत है कि ToString() बेस क्लास में किसी भी तरह से उपयोग किया जाएगा (जैसे उपयोगकर्ता को आउटपुट लिखना)। आम तौर पर, वे इस ओवरराइड को परिभाषित करने के बारे में नहीं सोचेंगे।


42
2017-07-21 10:38



Upvoted। यह एक महान उदाहरण है जो वास्तव में इस धागे में आता है। वही उदाहरण दिया गया था कहीं और पुराना जवाब तुलना के लिए, स्टैक ओवरफ़्लो पर। - Jeppe Stig Nielsen


दिलचस्प बात यह है कि सी # कंपाइलर के रोज़लिन संस्करण में एक सारणी ओवरराइड विधि है, जिसे मैंने इस बारे में एक लेख लिखने के लिए काफी अजीब पाया:

http://ericlippert.com/2011/02/07/strange-but-legal/


12
2018-01-18 06:45





कल्पना करो कि SecondAbstract एक तीन-वर्ग पदानुक्रम के बीच में है, और यह अपने आधार से कुछ अमूर्त तरीकों को लागू करना चाहता है FirstAbstract जबकि अपने बच्चे से कुछ अन्य विधि एक्स लागू किया जा रहा है ThirdAbstract

इस मामले में, SecondAbstract विधि एक्स को सजाने के लिए मजबूर किया जाता है abstract चूंकि यह एक कार्यान्वयन प्रदान नहीं करना चाहता है; साथ ही, इसे इसे सजाने के लिए मजबूर होना पड़ता है override चूंकि यह एक नई विधि एक्स को परिभाषित नहीं कर रहा है, लेकिन एक्स को अपने बच्चे को लागू करने की ज़िम्मेदारी लेना चाहता है। अत, abstract override

सामान्य रूप से, द्वारा बनाई गई अवधारणाएं abstract तथा override ऑर्थोगोनल हैं। पहली शक्तियों ने कक्षाओं को एक विधि को लागू करने के लिए व्युत्पन्न किया, जबकि दूसरा यह मानता है कि एक विधि आधार वर्ग पर निर्दिष्ट जैसा ही है, न कि new एक।

इसलिए:

  • न तो कीवर्ड: "सरल" विधि
  • abstract केवल: व्युत्पन्न वर्ग को लागू करना होगा
  • override केवल: आधार वर्ग में परिभाषित विधि का कार्यान्वयन
  • abstract override: व्युत्पन्न वर्ग को बेस क्लास में परिभाषित विधि को लागू करना होगा

6
2018-01-18 05:08



लेकिन द्वितीय श्रेणी को विधि एक्स को शामिल करने की आवश्यकता नहीं है, क्योंकि दूसरा सार एक सार वर्ग है। एक्स जोड़ना और इसे अमूर्त ओवरराइड के रूप में सजाने के बराबर एक्स समेत समतुल्य नहीं है, जो ओपी का मतलब है जो मुझे लगता है कि अनावश्यक है। - saus
इसका मतलब यह है कि SecondAbstract बेस क्लास के विधि एक्स कार्यान्वयन से संतुष्ट नहीं है? - Eranga


ऐसा इसलिए किया जाता है क्योंकि बाल वर्ग में आपके पास नहीं हो सकता है abstract आधार वर्ग के समान नाम के साथ विधि। override कंपाइलर को बताता है कि आप बेस क्लास के व्यवहार को ओवरराइड कर रहे हैं।

आशा है कि यह वही है जो आप खोज रहे हैं।


0
2018-01-18 05:07





अगर आपने घोषणा नहीं की है SomeMethodजैसा abstract override में SecondAbstract, संकलक उस वर्ग को विधि के कार्यान्वयन की अपेक्षा करेगा। साथ में abstract override यह स्पष्ट है कि कार्यान्वयन से प्राप्त वर्ग में होना चाहिए SecondAbstract और अंदर नहीं SecondAbstract अपने आप।

उम्मीद है की यह मदद करेगा...


0
2018-01-18 05:09





इस डिजाइन पैटर्न को टेम्पलेट विधि पैटर्न के रूप में जाना जाता है।

टेम्पलेट विधियों पर विकिपीडिया पेज

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

  • ले जाएँ ()
  • आक्रमण()
  • रिट्रीट ()
  • आराम()

आदि...


0
2018-06-09 18:00