में वर्चुअल कीवर्ड मुझे जावा का ज्ञान है और पिछले कुछ दिनों से सी # सीख रहा है। अब मैं "आभासी" कीवर्ड में आया हूं, जैसा कि this link पर सुझाया गया है, उप-वर्गों में संबंधित विधियों, गुणों आदि को ओवरराइड करने की अनुमति देने के लिए उपयोग किया जाता है। अब मुझे लगता है कि हम "आभासी" कीवर्ड का उपयोग किये बिना भी विधियों को ओवरराइड कर सकते हैं। तो यह जरूरी क्यों है?सी #
सी #
उत्तर
यदि आप वास्तव में override
उप वर्गों में विधियों को चाहते हैं तो आपको virtual
कीवर्ड की आवश्यकता है। अन्यथा आधार कार्यान्वयन नए कार्यान्वयन से छिपा होगा, जैसे कि आपने इसे new
कीवर्ड के साथ घोषित किया था।
उन्हें आधार विधि के बिना "अधिभावी" द्वारा तरीकों छिपाई जा रही है virtual
बहुरूपता के बिना आप छोड़ देता है की घोषणा की जा रही है, इसका मतलब है कि: यदि आप "आधार" संस्करण के लिए "डाली" एक विशेष संस्करण और कॉल के लिए एक विधि है, हमेशा आधार वर्ग कार्यान्वयन का उपयोग ओवरराइड संस्करण के बजाय किया जाएगा - जो आप उम्मीद नहीं करेंगे।
उदाहरण:
class A
{
public void Show() { Console.WriteLine("A"); }
}
class B : A
{
public void Show() { Console.WriteLine("B"); }
}
A a = new A();
B b = new B();
a.Show(); // "A"
b.Show(); // "B"
A a1 = b;
a1.Show(); // "A"!!!
अब मुझे लगता है कि हम "आभासी" कीवर्ड का उपयोग किये बिना भी विधियों को ओवरराइड कर सकते हैं।
नहीं, आप नहीं कर सकते। जावा के विपरीत, सी # सदस्यों में डिफ़ॉल्ट द्वारा सील कर दिए गए हैं और आप उन्हें तब तक ओवरराइड नहीं कर सकते जब तक कि आप उन्हें virtual
कीवर्ड से चिह्नित न करें।
virtual
को परिभाषित करने का एक तरीका है कि एक विधि एक डिफ़ॉल्ट कार्यान्वयन है , लेकिन उस कार्यान्वयन एक बच्चे कक्षा में ओवरराइड किया जा सकता है। वर्चुअल का उपयोग करने के अलावा, आप new
कीवर्ड (जो आम तौर पर खराब अभ्यास है) का उपयोग किए बिना सीधे एक विधि को ओवरराइड नहीं कर सकते हैं।
virtual
के कार्यान्वयन का एक अच्छा उदाहरण ToString()
विधि है। सी # में प्रत्येक ऑब्जेक्ट को ToString()
पर कॉल करने में सक्षम होने की गारंटी है क्योंकि प्रत्येक ऑब्जेक्ट बेस System.Object
कक्षा से प्राप्त होता है, जिसमें वर्चुअल विधि ToString()
होती है। व्युत्पन्न कक्षाएं हालांकि इसे ओवरराइड कर सकती हैं, और अपना स्वयं का कार्यान्वयन प्रदान कर सकती हैं जो वस्तु के उपयोगकर्ताओं के लिए अधिक उपयोगी हो सकती है।
अद्यतन: मैंने हाल ही में एक ब्लॉग पोस्ट लिखा है जो इस विषय में थोड़ी गहराई में जाता है। Check it out here।
इस उदाहरण पर एक नज़र डालें:
void Main()
{
var o1 = new S();
Console.WriteLine(((B)o1).m1());
}
public class B
{
public virtual string m1() {
return "m1";
}
}
public class S : B
{
override public string m1() {
return "overridden m1";
}
}
इस उदाहरण में उपवर्ग S
instantiated और चर o1
वस्तु को सौंपा गया है। Console.WriteLine
कथन के पैरामीटर में इसे बेस क्लास B
में डाला जा रहा है, तो विधि m1
कहा जाता है। क्योंकि हम उपवर्ग S
में आधार वर्ग B
और override
में virtual
का इस्तेमाल किया है, हम
आउटपुट के रूप मेंओवरराइड एम 1 हो रही है
।आप उपवर्ग S
में B
और override
में m1
की विधि घोषणा में virtual
को निकाल देते हैं तो आप
आउटपुट के रूप मेंएम 1
हो रही है, जिसका अर्थ है डाली भी प्रभाव पड़ता है कि बेस क्लास B
में विधि m1
की मूल घोषणा का उपयोग किया जाता है।
एनबी। आप इस तरह के
new public string m1() {
return "overridden m1";
}
यह सोचते हैं कि आधार वर्ग B
में virtual
कीवर्ड अनुपस्थित है के रूप में उपवर्ग S
में new
कीवर्ड का उपयोग कर रहे हैं, तो, आप उत्पादन
एम 1
हो रही है
भी। यदि आप इसे B
पर नहीं डालेंगे, तो नई विधि का उपयोग किया जाएगा। इसे (या छुपा) एक विधि (बेस क्लास की मूल विधि) को छायांकित किया जाता है।
सारांश:
एक विधि है, जो भी प्रभावी अगर तुम आधार वर्ग के लिए डाली होना चाहिए ओवरराइड करने के लिए, उप वर्ग में आधार वर्ग में
virtual
कीवर्ड औरoverride
का उपयोग करें।यदि आप विधि को ओवरराइड करना चाहते हैं, जो केवल उप वर्ग में सक्रिय होना चाहिए, तो उप-वर्ग विधि घोषणा में
new
कीवर्ड का उपयोग करें। जैसा कि आपने देखा है कि यह इसके बिना भी काम करता है, लेकिन यह बेहतर है अगर यह वहां है तो हर कोई जानता है कि यह विधि का एक नया संस्करण है।
"अब मुझे लगता है कि हम 'वर्चुअल' कीवर्ड का उपयोग किये बिना भी विधियों को ओवरराइड कर सकते हैं।" आपको लगता है? – BoltClock
@ बोल्टक्लॉक निश्चित रूप से। मूल वर्ग में 'सार 'और व्युत्पन्न कक्षा में' ओवरराइड 'पर्याप्त हैं। 'वर्चुअल' की आवश्यकता नहीं: पी – CodesInChaos
हां, वर्चुअल का अर्थ है" मैं एक कार्यान्वयन प्रदान कर रहा हूं, लेकिन आप इसे पॉलिमॉर्फिक रूप से ओवरराइड कर सकते हैं "और सार का अर्थ है" मैं कुछ परिभाषित कर रहा हूं जिसके लिए आपको एक कार्यान्वयन प्रदान करना होगा, जो बहुरूप रूप से कार्य करेगा "। छायांकन के विपरीत (जिसे आम तौर पर उप-इष्टतम माना जाता है), फ़ंक्शन हस्ताक्षर मेल खाना चाहिए। –