2012-11-13 11 views
5

"व्युत्पन्न से हैलो" की अपेक्षा। लेकिन "बेस से हैलो" प्राप्त करना।व्युत्पन्न वर्ग विधि के बजाय बेस क्लास विधि क्यों कहा जाता है?

class Program 
{ 
    interface IBase 
    { 
     void Method(); 
    } 

    public class Base: IBase 
    { 
     public virtual void Method() 
     { 
      Console.WriteLine("Hello from the base."); 
     } 
    } 

    public class Derived : Base 
    { 
     public virtual new void Method() 
     { 
      Console.WriteLine("Hello from the derived."); 
     } 
    } 

    static void Main(string[] args) 
    { 
     IBase x = new Derived(); 
     x.Method(); 
    } 
} 

तो व्युत्पन्न कक्षा की विधि क्यों नहीं कहा जाता है। और सबसे महत्वपूर्ण बात यह है कि, व्युत्पन्न प्रकार को एक्स कास्टिंग किए बिना कॉल करने के लिए व्युत्पन्न कक्षा विधि कैसे प्राप्त कर सकता हूं?

मेरे वास्तविक एप्लिकेशन में, आईबीएएस के कई अन्य संबंधित तरीके हैं और व्युत्पन्न केवल आईबीएएस में दो विधियों को प्रतिस्थापित करता है।

उत्तर

6

आप new संशोधक आप विशेष रूप से कह रहे हैं कि विधि है कि पदानुक्रम के लिए आभासी प्रेषण श्रृंखला का हिस्सा नहीं है, इसलिए आधार वर्ग में इसी नाम से विधि बुला का उपयोग करते हैं करने के लिए पुनर्निर्देशन का कारण नहीं बनेगा बाल वर्ग यदि आप new के बजाय override के साथ विधि को चिह्नित करते हैं तो आपको वर्चुअल प्रेषण दिखाई देगा जिसे आप देखना चाहते हैं।

आपको व्युत्पन्न कक्षा की विधि से virtual को हटाने की आवश्यकता होगी क्योंकि आप override विधि virtual (यह पहले से ही) के रूप में चिह्नित नहीं कर सकते हैं।

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

public interface IFoo 
{ 
    void Foo(); 
} 

public class A : IFoo 
{ 
    public void Foo() 
    { 
     Console.WriteLine("I am A, hear me roar!"); 
    } 
} 

public class B : IFoo 
{ 
    public void Foo() 
    { 
     Console.WriteLine("I am B, hear me roar!"); 
    } 
} 

private static void Main(string[] args) 
{ 
    IFoo foo = new A(); 
    foo.Foo(); 

    foo = new B(); 
    foo.Foo(); 

    Console.WriteLine(); 
    Console.WriteLine("Press any key to exit . . ."); 
    Console.ReadKey(true); 
} 
+0

+10। –

+0

आपको सुझाव दिया गया है कि समाधान निर्माण योग्य नहीं है। कंपाइलर शिकायत करता है कि "सदस्य ओवरराइड नहीं कर सकता है प्रोग्राम.बेस.मेथ() 'क्योंकि यह वर्चुअल, सार, या ओवरराइड चिह्नित नहीं है। – estimpson

+0

मूल विधि को' आभासी 'और व्युत्पन्न विधि' ओवरराइड 'चिह्नित किया जाना चाहिए। –

2

अपने बच्चे वर्ग में virtual new के बजाय override कीवर्ड का उपयोग करें।

इसलिए, अपने कोड दिखना चाहिए:

class Program 
{ 
    interface IBase 
    { 
     void Method(); 
    } 

    public class Base: IBase 
    { 
     public virtual void Method() 
     { 
      Console.WriteLine("Hello from the base."); 
     } 
    } 

    public class Derived : Base 
    { 
     public override void Method() // The magic happens here! 
     { 
      Console.WriteLine("Hello from the derived."); 
     } 
    } 

    static void Main(string[] args) 
    { 
     IBase x = new Derived(); 
     x.Method(); 
    } 
} 

के रूप में वर्णित here, new कीवर्ड माता पिता विधि है, जो आप देख रहे हैं नहीं है छिपाने के लिए प्रयोग किया जाता है।

+3

कि और new' का उपयोग नहीं करते '। – cadrell0

+0

+10 यदि आप अपने उत्तर में सही कोड जोड़ते हैं। –

+0

@ SteveHémond मैं उसे एक शब्द की बदलती दिखाने के लिए कोड जोड़ने के लिए कोई ज़रूरत नहीं देखते हैं, लेकिन यह अच्छा होगा के लिए इस सवाल का जवाब सही ढंग से जो शब्द सही करने की (नए और आभासी) या समझाने के लिए क्यों महत्वपूर्ण है की जरूरत का उल्लेख। – Servy

3

यह काम पर मूल polymorphism है।

व्यवहार आप के लिए, आप विरासत में मिला विधि ओवरराइड करने के लिए अपने व्युत्पन्न विधि सेट करने की आवश्यकता होगी देख रहे हैं के लिए:

public class Derived : Base 
{ 
    public override void Method() 
    { 
     Console.WriteLine("Hello from the derived."); 
    } 
} 
1

new कीवर्ड एक नई विधि बनाता है और कहता है कि आधार प्रक्रिया गुप्त रखी है। लेकिन यह केवल आपके व्युत्पन्न वर्ग के उपभोक्ताओं के लिए है, क्योंकि बेस क्लास कोड इसके बारे में कुछ भी नहीं जानता है।

override कीवर्ड बेस क्लास कार्यान्वयन को एक नए के साथ ओवरराइड करता है।

class Program 
{ 
    interface IBase 
    { 
     void Method(); 
    } 

    public class Base: IBase 
    { 
     public virtual void Method() 
     { 
      Console.WriteLine("Hello from the base."); 
     } 
    } 

    public class Derived : Base 
    { 
     // the next line was changed. 
     public override void Method() 
     { 
      Console.WriteLine("Hello from the derived."); 

      // note that if you want to call the original implementation, you do it like this: 
      base.Method(); 
     } 
    } 

    static void Main(string[] args) 
    { 
     Base x = new Derived(); 
     x.Method(); 
    } 
} 
0

में व्युत्पन्न केवल एक व्युत्पन्न उदाहरण, यह प्रभावी रूप से छुपाता है जहां आधार कार्यान्वयन में मौजूद है new'd विधि।

लेकिन घोषित प्रकार केवल बेस के कार्यान्वयन जानता है, तो यह है कि कहते हैं।

आपके प्रश्न का उत्तर करने के लिए, व्युत्पन्न के कार्यान्वयन तुम क्या चाहते हैं कॉल करने के लिए:

Derived d = new Derived(); 
d.Method(); 
((IBase)d).Method(); 

//Prints: 
//Hello from the derived. 
//Hello from the base. 
संबंधित मुद्दे