2010-12-17 17 views
11

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

public interface ITestInterface 
{ 
void virtualmethod(); // this method is by default virtual. 
} 

public class TestInterface :ITestInterface 
{ 
public virtual void virtualmethod() 
{ 
// Now compiler should consider that i am actually hiding the interface virtual method. 
} 
} 

अगर आप उपरोक्त कोड इंटरफेस और ILDASM में खुला के लिए आप इस तरह का कोड दिखाई देगा का निर्माण: .method public hidebysig newslot abstract virtual instance void virtualmethod() cil managed { }//end of method ITestInterface::virtualmethod

+2

वर्चुअल के बजाय, यह मानते हुए कि इंटरफ़ेस में विधियां डिफ़ॉल्ट रूप से सार होती हैं, और अधिक समझ में आता है। –

+0

हाँ यह ठीक है लेकिन एक बार जब अनुयायी विधि के साथ वर्चुअल संलग्न करता है और विधि को कार्यान्वित करते समय आप वर्चुअल डाल रहे हैं तो शिकायतकर्ता को यह कहना चाहिए कि आप मूल घोषणा छुपा रहे हैं। –

उत्तर

39

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

interface IAnimal 
{ 
    string Speak(); 
} 

class Dog : IAnimal 
{ 
    public string Speak() 
    { 
     return "Bark!"; 
    } 
} 

Dog वर्ग है इंटरफेस को लागू अनुबंध IAnimal के एक कार्यान्वयन प्रदान करके:

इस उदाहरण पर विचार। यहां कोई वर्चुअल विधियां नहीं हैं और कोई ओवरराइड नहीं है।

interface IAnimal 
{ 
    string Speak(); 
} 

class Dog : IAnimal 
{ 
    public virtual string Speak() 
    { 
     return "Bark!"; 
    } 
} 

class GoldenRetriever : Dog 
{ 
    public override string Speak() 
    { 
     return "I am a golden retriever who says " 
        + base.Speak(); 
    } 
} 

अब Dog वर्ग Speak की घोषणा की है virtual व्युत्पन्न की अनुमति देता है जो कक्षाएं एक अतिरिक्त या नए कार्यान्वयन प्रदान करने के लिए होने के लिए:

अब इस उदाहरण पर विचार करें। यह IAnimal के साथ अनुबंध को तोड़ता नहीं है क्योंकि Speak विधि पर कोई भी कॉल अभी भी एक स्ट्रिंग देता है।

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

interface IAnimal 
{ 
    string Speak(); 
} 

abstract class Dog : IAnimal 
{ 
    public abstract string Speak(); 
} 

class GoldenRetriever : Dog 
{ 
    public override string Speak() 
    { 
     return "I am a golden retriever"; 
    } 
} 

सूचना अब कि Dog वर्ग बिल्कुल Speak के लिए कोई कार्यान्वयन प्रदान करता है अभी तक अनुबंध की शर्तों को पूरा किया गया है।

इंटरफेस भी Dog और GoldenRetrieverIAnimal इंटरफ़ेस को लागू उपरोक्त दोनों सभी उदाहरणों में ऐसा वर्ग के लिए वर्ग से लिए गए हैं। न तो Speak विधि छुपाएं - दोनों कक्षा लागू करें।


ठीक है, मुझे लगता है कि आपका भ्रम इस तथ्य से आ रहा है कि वर्चुअल विधि को एक इंटरफ़ेस में परिभाषित किया गया है, कक्षा नहीं।यहाँ आईएल इंटरफेस के लिए मैं ऊपर परिभाषित है:

.class private interface abstract auto ansi IAnimal 
{ 
    .method public hidebysig newslot abstract 
     virtual instance string Speak() cil managed 
    { 
    } 
} 

आप सही है कि विधि virtual के रूप में आप भी सूचना के लिए उस प्रकार यहां एक interface रूप में नामित है की जरूरत है परिभाषित किया गया है कर रहे हैं है। यह पूरी तरह से माइक्रोसॉफ्ट के सी # कंपाइलर द्वारा उत्पन्न एमएसआईएल का कार्यान्वयन विवरण है - एक और कंपाइलर आसानी से अलग-अलग कोड उत्पन्न कर सकता है जब तक कि अर्थात् यह वही परिणाम प्रदान करता है।

यहां महत्वपूर्ण बात यह है कि: इस विधि को इंटरफ़ेस में virtual के रूप में घोषित किया गया है, इसका मतलब यह नहीं है कि यह कक्षा में घोषित virtual विधि जैसा ही है।

+0

कृपया प्रश्न को फिर से जांचें क्योंकि मैंने उसी –

+0

के लिए आईएल कोड जोड़ा है। विधि सार्वजनिक hidebysig newslot सार वर्चुअल इंस्टेंस शून्य वर्चुअल मोड() cil प्रबंधित {} // विधि का अंत ITestInterface :: virtualmethod –

2

इंटरफ़ेस बेस क्लास नहीं है, इसलिए कार्यान्वयन विधियां ओवरराइड नहीं हैं। इंटरफ़ेस केवल विधियों की घोषणा करता है, इंटरफ़ेस विधियां डिफ़ॉल्ट रूप से आभासी नहीं हैं, असंगत इंटरफेस केवल उस इंटरफ़ेस को लागू करने वाले वर्ग पर उपलब्ध विधियों की घोषणा करते हैं।

घोषणा वर्चुअल नहीं हो सकती है।

कार्यान्वयन कार्यान्वयनकर्ता के तर्क पर पूरी तरह से निर्भर आभासी हो सकता है या नहीं हो सकता है।

+0

इंटरफेस वर्चुअल के साथ एक प्रकार है तरीकों से व्यवहार कक्षाओं के समान होना चाहिए। –

+1

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

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

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