2011-08-24 13 views
11

संभव है? क्या आप पर कुछ भी से कुछ भी तक पहुंच सकते हैं?सी # सार्वजनिक सदस्य को ओवरराइड करें और इसे निजी बनाएं

+5

मैं प्रति दिन कम से कम एक बार सटीक टाइपो लिखता हूं। –

+1

@ फिल: नहीं, ओपी ने सही आईएमओ लिखा था। ;) – Yuck

+0

वाह मैंने तय नहीं किया जब तक कि यह तय नहीं किया गया –

उत्तर

14

नहीं, आप छिपाने कर सकते हैं एक उपवर्ग में एक निजी विधि के साथ एक सार्वजनिक सदस्य है, लेकिन आप नहीं कर सकते हैं ओवरराइड एक उपवर्ग में एक निजी एक के साथ एक सार्वजनिक सदस्य। और, वास्तव में, यह सिर्फ एक सार्वजनिक/निजी चीज़ नहीं है, यह आम तौर पर पहुंच को कम करने के लिए लागू होता है।

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

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

public class BaseClass 
{ 
    public virtual void A() { } 

    public virtual void B() { } 
} 

public class SubClass 
{ 
    // COMPILER ERROR, can't override to be more restrictive access 
    private override void A() { } 

    // LEGAL, you can HIDE the base class method, but which is chosen 
    // depends on level accessed from 
    private new void B() { } 
} 

तो SubClass.B() ही आधार वर्ग के तरीकों को छुपाता है जब यह सुलभ है। यही है, अगर आप को SubClass के अंदर कॉल करते हैं तो यह B() का छुपा रूप लेगा, लेकिन B() निजी है, यह स्वयं के बाहर कक्षाओं के लिए दृश्यमान नहीं है, और इस प्रकार वे अब भी BaseClass.B() देखेंगे।

लंबी और यह की कमी है:

1) आप एक विधि ओवरराइड नहीं कर सकते और अधिक प्रतिबंधात्मक (पहुँच बुद्धिमान होने के लिए)। 2) आप एक अधिक प्रतिबंधक के साथ एक विधि छुपा सकते हैं, लेकिन इसका प्रभाव केवल तभी होगा जब वह नया एक्सेस प्रकार दिखाई दे, अन्यथा आधार एक खड़ा हो।

public class BaseClass 
{ 
    public virtual void A() { } 
    public virtual void B() { } 
} 

public class SubClass : BaseClass 
{ 
    public virtual void A() { B(); } 

    // legal, you can do this and B() is now hidden internally in SubClass, 
    // but to outside world BaseClass's B() is still the one used. 
    private new void B() { } 
} 

// ... 

SubClass sc = new SubClass(); 
BaseClass bc = new BaseClass(); 

// both of these call BaseClass.B() because we are outside of class and can't 
// see the hide SubClass.B(). 
sc.B(); 
bc.B(); 

// this calls SubClass.A(), which WILL call SubClass.B() because the hide 
// SubClass.B() is visible within SubClass, and thus the hide hides BaseClass.B() 
// for any calls inside of SubClass. 
sc.A(); 
+0

क्या आप इसके बारे में निश्चित हैं? ऐसा लगता है कि यह लिस्कोव के –

+0

को तोड़ देगा आप इसे कर सकते हैं। हालांकि, आप इसे 'बेस क्लास' पर डाल सकते हैं और विधि को कॉल कर सकते हैं जैसे कुछ भी नहीं हुआ। – Femaref

+0

@ ब्रायन: हाँ, अधिक प्रतिबंधक बनाने के लिए छिपाने की अनुमति है। ठीक संकलित करता है।याद रखें कि विधि अभी भी मौजूद है, और जब तक आप इसे बेस क्लास संदर्भ के रूप में देखते हैं, तब भी यह वहां है और चलता है, यह केवल उप-वर्ग (निजी छिपाने के मामले में) से दिखाई नहीं देता है। यह नहीं कह रहा कि यह हमेशा सबसे अच्छा विकल्प है, ओओ बुद्धिमान, लेकिन सी # में यह संभव है। –

3

नहीं।

इससे निपटने का एक सामान्य तरीका NotImplementedException या उस प्रभाव से कुछ फेंकना है।

+6

'NotImplementedException' का अर्थ गलती से छोड़ा गया कुछ नहीं है। 'NotSupportedException' का अर्थ डिजाइन द्वारा छोड़ा गया कुछ नहीं है (और संभवतः * अभी भी * गलती से, जैसा भी मामला हो)। –

2

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

public class A : B 
{ 
    public new void Foo() 
    { 
     base.Foo(); 
    } 
} 
+2

यह ** से अधिक ** सवारी ** नहीं है, यह ** से अधिक ** लिखना है **। यदि आप इस वर्ग को 'बी' पर डालते हैं, तो विधि उपलब्ध होगी, भले ही आप इसे 'ए' में ओवरराइट करते हैं। – Femaref

+0

@ फेमेरेफ़ तकनीकी रूप से सही- सही प्रकार का अधिकार। –

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