2010-04-30 17 views
8

यहां मेरी स्थिति है:बेस क्लास क्यों कहा जाता है?

interface Icontainer{ 
string name(); 
} 

abstract class fuzzyContainer : Icontainer{ 
    string name(){ 
    return "Fuzzy Container"; 
    } 
} 

class specialContainer: fuzzyContainer{ 
    string name(){ 
    return base.name() + " Special Container"; 
    } 
} 


Icontainer cont = new SpecialContainer(); 
cont.name(); // I expected "Fuzzy Container Special Container" as the output. 

जब मैं आउटपुट के ऊपर वर्णित अनुसार अपना कोड चलाता हूं तो बस "फ़ज़ी कंटेनर" होता है। मुझे यहां क्या समझ नहीं आ रहा है? वांछित परिणाम प्राप्त करने का कोई बेहतर तरीका है?

+1

यह कोड संकलित नहीं है .. और अभी भी नया स्पेशलकॉन्टर को विशेषकंटर में बदलने के बाद भी नहीं। –

+0

यह मानना ​​नहीं है कि कोड को सिंटैक्टिक रूप से सही किया गया है, उदाहरण के लिए कोड – IaCoder

उत्तर

17

यदि आप नाम() virtual और फिर override विशेषकंटनर में करते हैं, तो आपको अपेक्षित व्यवहार मिल जाएगा।

public interface Icontainer 
{ 
    string name(); 
} 

public abstract class fuzzyContainer : Icontainer 
{ 
    public virtual string name() 
    { 
     return "Fuzzy Container"; 
    } 
} 

public class specialContainer : fuzzyContainer 
{ 
    public override string name() 
    { 
     return base.name() + " Special Container"; 
    } 
} 
3

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

यदि आप था:

SpecialContainer cont = new SpecialContainer(); 
cont.name(); 

तो फिर तुम भी उत्पादन आप उम्मीद मिल जाएगा।

मैट का उत्तर भी काम करता है और यदि आप वर्चुअल वर्चुअल बनाने के लिए बेस क्लास को संपादित कर सकते हैं तो बेहतर हो सकता है। डिफ़ॉल्ट तरीकों से virtual कीवर्ड

0

उस वर्ग में 'नाम' विधि फ़ज़ी कंटनर की नाम विधि का ओवरराइड नहीं है, तब तक ओवरराइड करने योग्य नहीं है। तो जब आप विशेष कंटेनर ऑब्जेक्ट को आईकॉन्टेनर के रूप में डालते हैं, तो इसमें केवल बेस क्लास 'नाम विधि का आह्वान होता है।

3

आपको नाम-विधि वर्चुअल घोषित करने और व्युत्पन्न कक्षा में ओवरराइड करने की आवश्यकता है।

मैंने आपके कोड को सबसे आम नामकरण सम्मेलनों के साथ "फिक्सिंग" की स्वतंत्रता भी ली।

abstract class FuzzyContainer : IContainer{ 
    protected virtual string GetName(){ 
    return "Fuzzy Container"; 
    } 
} 

class SpecialContainer: FuzzyContainer{ 
    override string GetName(){ 
    return base.GetName() + " Special Container"; 
    } 
} 
6

सबसे पहले, यह उपयोगी है जब आपके पास प्रश्न हैं जो वास्तव में संकलित कोड पोस्ट करते हैं। किसी समस्या का विश्लेषण करना मुश्किल है जब यह अनुपलब्ध संशोधक और टाइपोज से भरा हुआ है; यह जानना मुश्किल है कि समस्या टाइपो है या नहीं।

एक बार जब हम आपके प्रोग्राम को ठीक करने के लिए काम करते हैं तो यह वास्तव में संकलित करता है, संकलक एक चेतावनी उत्सर्जित करता है जो आपको बताता है कि ओवरलोडिंग गलत लगती है। चूंकि आपका प्रश्न है "ओवरलोडिंग गलत क्यों है?" यह संकलक चेतावनी को पढ़ने के लिए शायद एक अच्छा विचार होगा कि हमने ठीक से उत्सर्जित किया ताकि आप इस समस्या का विश्लेषण कर सकें।

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

इस समस्या को ठीक करने के दो तरीके हैं, इस पर निर्भर करते हुए कि इरादा "नया" या "ओवरराइड" होने का तरीका है। यदि आप "ओवरराइड" होने का तरीका चाहते हैं तो आधार कार्यान्वयन वर्चुअल और व्युत्पन्न कार्यान्वयन ओवरराइड करें।

आप विधि 'नई' हो सकता है और लिए आप अभी भी नई विधि इंटरफेस कार्यान्वयन के लिए बाध्य बदलना चाहते हैं तो इंटरफ़ेस reimplementation का उपयोग इरादा हैं:

class SpecialContainer: FuzzyContainer, IContainer 
{ 
    public new string Name() 
    { 
    return base.Name() + " Special Container"; 
    } 
} 

सूचना 'नई' और तथ्य यह है कि हमारे पास फिर से कहा गया है कि यह वर्ग आईसीओन्टैनर लागू करता है। यह संकलक को बताता है "बेस क्लास से निकाले गए आईकॉन्टेनर के तरीकों से बाइंडिंग को नजरअंदाज करें और शुरू करें।"

+0

क्या कोई वास्तव में आकर्षक परिस्थितियां हैं जहां आप 'new' का उपयोग करेंगे? मुझे लगता है कि मैं केवल 'नया' उपयोग कर रहा हूं, जब मैं एक डिजाइन को मजबूर करने का प्रयास कर रहा हूं, मुझे नहीं होना चाहिए। –

+4

@ मैट: आईनेमेरेबल आईनेमरेबल बढ़ाता है। दोनों में GetEnumerator नामक एक विधि है जिसमें कोई तर्क नहीं होता है। आपके पास तीन विकल्प हैं। (1) जेनेरिक संस्करण प्रकार को नोंगनेरिक संस्करण के साथ संगत न करें; विस्तार संबंध तोड़ो। (2) व्युत्पन्न इंटरफ़ेस में GetEnumerator के लिए एक अलग नाम के साथ आते हैं। या (3) व्युत्पन्न संस्करण के GetEnumerator को "नई" विधि बनाएं। आपको लगता है कि इन तीन बुरे विकल्पों में से कम से कम भयानक कौन सा है? मैं (3) के लिए जाना होगा। –

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