2010-05-06 9 views
22

क्या कक्षा को 'निकालने' विधियों को विरासत में मिला है?क्या कक्षा को 'निकालने' विधियों को विरासत में मिला है?

उदा। अगर मैं नहीं चाहता कि मेरी कक्षा ToString() विधि हो, तो क्या मैं कुछ कर सकता हूं ताकि यह अब उपलब्ध न हो?

+2

http://www.codinghorror.com/blog/2004/08/inherits-nothing.html – Svisstack

+1

यह "इनकार कर दिया वसीयत" कोड गंध के रूप में जाना जाता है:: "एक वर्ग

प्रलेखन से

जो बेस क्लास की एक विधि को इस तरह से ओवरराइड करता है कि बेस क्लास का अनुबंध व्युत्पन्न वर्ग द्वारा सम्मानित नहीं किया जाता है "। http://en.wikipedia.org/wiki/Code_smell – Mathias

+0

कोई विधि हटाने का कोई तरीका नहीं है। यदि विधि 'आभासी' ('वर्चुअल', 'सार', या 'ओवरराइड' के साथ चिह्नित है), तो आप भाग्यशाली हैं क्योंकि बेस क्लास के लेखक ने आपको विधि के व्यवहार का निर्णय लेने की अनुमति दी है। आप इसे कुछ भी नहीं कर सकते हैं, या अपवाद फेंक सकते हैं (लेकिन ध्यान दें कि यह आपकी विधि से बेस क्लास की अपेक्षा को तोड़ सकता है, इसलिए यह _some_ मामलों में समस्याएं पेश करेगा)। यदि विधि गैर-वर्चुअल है, तो आप बहुत कुछ नहीं कर सकते हैं। इसे किसी अन्य विधि से छिपाना एक बहुत बुरा विचार है (और इसे बिल्कुल नहीं हटाता है)। –

उत्तर

28

नहीं - यह Liskov's Substitution Principle का उल्लंघन करेगा। आपको हमेशा एक उप प्रकार के उदाहरण का उपयोग करने में सक्षम होना चाहिए जैसे कि यह एक सुपरटेप का उदाहरण था।

यह न भूलें कि एक कॉलर केवल आपके प्रकार के "बेस" या इंटरफेस के बारे में जागरूक हो सकता है। इस कोड पर विचार करें:

object foo = new TypeWithToStringRemoved(); 
foo.ToString(); 

इसे संकलित करना होगा, है ना? अब आप निष्पादन समय पर क्या होने की उम्मीद करेंगे?

अब ToString के लिए, GetHashCode, Equals और GetType कोई रास्ता नहीं उन्हें पहली जगह में से बचने के लिए है - लेकिन पता चलता है आम तौर पर अगर वहाँ, विधियों आप एक आधार प्रकार से "निकालें" करना चाहते हैं कि आप विरासत में नहीं किया जाना चाहिए इससे पहले स्थान पर। व्यक्तिगत रूप से मुझे लगता है कि विरासत की भूमिका ऑब्जेक्ट उन्मुख प्रोग्रामिंग में कुछ हद तक अधिक है: जहां यह उपयोगी है वास्तव में उपयोगी है, लेकिन आम तौर पर मैं मूल वर्गों की बजाय संरचना को प्राथमिकता देता हूं, और आधार वर्गों के बजाय अमूर्तता के रूप में इंटरफेस करता हूं।

+1

आप पूरी तरह से सही हैं - 'ToString()' विधि अपवाद फेंकने के लिए विशेष रूप से खतरनाक है। आपके द्वारा दिखाए गए (से इसे सीधे कॉल करने) की तुलना में 'ToString()' के बहुत अधिक * छुपा * उपयोग हैं। – tanascius

+0

लेकिन आप किसी भी सिद्धांत को तोड़ने या अप्रत्याशित अपवादों को फेंकने के बिना, विरासत में सदस्य को छिपाने के लिए 'नया' संशोधक का उपयोग कर सकते हैं (और एक नॉट्सपोर्टेड अपवाद, जैसे तानसियस सुझाव दिया गया है) फेंक सकते हैं। –

+0

@ एलनॉन: यह हमेशा अप्रत्याशित होगा, जब 'ToString()' कॉल अपवाद फेंकता है ... – tanascius

15

आप एक NotSupportedException फेंक कर सकते हैं, Obsolete के रूप में चिह्नित है और उपयोग EditorBrowsable:

[EditorBrowsable(EditorBrowsableState.Never)] 
[Obsolete("...", false)] 
void YourMethod() 
{ 
    throw new NotSupportedException("..."); 
} 

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

+0

@tanascius: यदि आपको अप्रचलित संपत्ति से अपवाद बहस मिलती है, तो आपका कोड अच्छा होगा ;-) – Svisstack

+0

@Svisstack: नहीं, यह दो अलग-अलग तार हैं ^^ शायद उन्हें अलग होना चाहिए, क्योंकि * अप्रचलित * संदेश डेवलपर के लिए है, जबकि * अपवाद * संदेश उपयोगकर्ता को फिर से पहुंचा सकता है? खैर, शायद नहीं - कम से कम यह नहीं होना चाहिए। – tanascius

+0

ठीक है, आपने बचाव किया ;-) – Svisstack

1

शॉर्ट आयनसर, नहीं, क्योंकि ऑब्जेक्ट और ऑब्जेक्ट से प्राप्त सभी वर्गों के पास यह विधि है।

4

जैसा कि अन्य ने इंगित किया है, आप किसी विधि को "हटा नहीं सकते", लेकिन अगर आपको लगता है कि इससे आपको किसी तरह से परेशान किया गया है तो आप hide it (अपनी कक्षा में) कर सकते हैं।

class Base 
{ 
    public static void F() {} 
} 
class Derived: Base 
{ 
    new private static void F() {} // Hides Base.F in Derived only 
} 
class MoreDerived: Derived 
{ 
    static void G() { F(); }   // Invokes Base.F 
} 
+0

एफ संरक्षित किया जाना चाहिए ना? –

+0

@ क्रिस्टोफ़ेडेवॉव यह उदाहरण सीधे एमएसडीएन से है, इसलिए मुझे लगता है कि इसका मतलब निजी होना है। – R0MANARMY

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