2013-08-07 14 views
8

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

नीचे मेरा उदाहरण देखें। मुझे orignal रखने की जरूरत है। MyClass सार्वजनिक तो कृपया एक जवाब के रूप में सुझाव नहीं है। ऐसा लगता है कि जावा से सी #

public class orignal.MyClass{ 
    public void MyMethod() 
    { 
    // Do something 
    } 
} 

class fake.MyClass: orignal.MyClass { 
    // How to prevent the following 
    public new void MyMethod() 
    { 
    // Do something different 
    } 
} 

संपादित करें: डुप्लिकेट नहीं।

सभी उत्तरों का सुझाव है, किसी विधि को व्युत्पन्न कक्षा में छुपा/छायांकित होने से रोकने के लिए संभव नहीं है। कुछ पुराने जावा कोड को सी # में माइग्रेट करते समय यह स्पष्ट हो गया। जावा में एक अंतिम विधि किसी भी व्युत्पन्न कक्षा में किसी भी विधि हस्ताक्षर का उपयोग नहीं करने देगी। हालांकि अधिकांश परिदृश्यों में यह बहुत अच्छा है कि सी # व्युत्पन्न वर्ग में एक ही हस्ताक्षर की विधि की अनुमति देता है, यदि आवश्यक हो तो ऐसे व्यवहार को रोकने के लिए यह बहुत अच्छा होगा।

+0

संभावित डुप्लिकेट [सी # में जावा के फाइनल के बराबर क्या है?] (Http://stackoverflow.com/questions/1327544/what-is-the-equivalent-of-javas-final-in-c)। .. –

+2

जैसा कि @Reed द्वारा उल्लेख किया गया है, 'यह शायद ही कभी मायने रखता है'। आपका कोड अभी भी मूल विधि को कॉल करेगा। –

+1

डुप्लिकेट नहीं। मैं समकक्ष के लिए नहीं पूछ रहा हूँ। मैं सुझाव दे रहा हूं कि इस उपयोग के मामले में कोई अस्तित्व में नहीं है। – JAson

उत्तर

9

// कैसे को रोकने के लिए निम्नलिखित

इसे रोकने का कोई तरीका नहीं है। यह भाषा द्वारा अनुमत है।

ध्यान दें कि, व्यावहारिक रूप से, यह शायद ही कभी मायने रखता है। यदि आप अपनी कक्षा को अपनी कक्षा के रूप में उपयोग करने की अपेक्षा करते हैं, तो आपकी विधि अभी भी कॉल की जाएगी। का उपयोग DerivedClass का उपयोग करते हुए एक चर से DerivedClass के रूप में उपयोग करते समय केवल विधि को छुपाता है।

इसका मतलब है कि यदि आपका एपीआई MyClass के आसपास बनाया गया है, तो हमेशा आपके विधियों में उदाहरण पारित होने पर MyMethod पर कॉल किया जाएगा। टिप्पणी के जवाब में


संपादित करें:

public sealed class MyClass 
{ 

:

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

+0

मैंने एक संपादन किया। मेरे एपीआई (एलिस कहें) का उपयोग करने वाले किसी व्यक्ति के लिए एक बहुत ही आसानी से संभव है जिसमें एक ही नाम वाला वर्ग है और फिर यदि यह रैपर किसी अन्य व्यक्ति द्वारा उपयोग किया जाता है, तो यह ऐलिस को MyMethod के व्यवहार को फिर से परिभाषित करने की अनुमति देगा () और संभावित रूप से एक अनजान अंत-डेवलपर को बेवकूफ़ बनाते हैं – JAson

+1

@ जेसन वास्तव में नहीं - डेवलपर को आपके बजाय अन्य व्यक्ति का नामस्थान शामिल करना होगा, या पूरी तरह से योग्यता प्राप्त करना होगा। किसी भी तरह से, उन्हें पता होना होगा कि वे क्या कर रहे हैं। –

+0

@ जेसन जो _overriding_ है, _hiding_ नहीं। किसी विधि को छिपाने से बेस क्लास पर कोई प्रभाव नहीं पड़ता है। –

3

आप सार्वजनिक विधि या संपत्ति को मुखौटा नहीं रोक सकते हैं, लेकिन आप क्यों? यह किसी भी व्यक्ति को बेस क्लास को ऐसा करने के लिए एक जानबूझकर कार्रवाई करता है (यानी उन्हें new टाइप करने की आवश्यकता है), इसलिए वे इसे करने का इरादा रखते हैं, क्यों कोशिश करें और उन्हें रोकें?

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

0

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

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

+0

प्रश्न बहुत स्पष्ट लगता है कि यह नए कीवर्ड के बारे में है और ओवरराइडिंग को रोक नहीं रहा है ... – Chris

+0

ध्यान दें कि सी # में आप एक विधि को 'मुहरबंद' के रूप में भी चिह्नित कर सकते हैं जो जावा में 'अंतिम' के समान रूप से समान रूप से कार्य करता है। आप वास्तव में एक वर्चुअल विधि सील कर सकते हैं। अर्थात। एक व्युत्पन्न वर्ग द्वारा अधिलेखित वर्चुअल विधि होने पर, लेकिन इसे आगे की परिभाषाओं को रोकने के लिए इसे सील करना। – Servy

+1

@ जेसन आप निश्चित रूप से * बेस क्लास में एक विधि को सील कर सकते हैं। आप इसे पूरी तरह से ओवरराइड होने से रोक सकते हैं, लेकिन आप इसे * नए * का उपयोग करके छायांकित होने से कभी नहीं रोक सकते हैं, क्योंकि हर किसी ने आपको बताया है। यह सिर्फ तथ्य है। – Servy

0

मुझे लगता है कि एक ही रास्ता इंटरफ़ेस यह के भीतर अपने विधि परिभाषा डाल बनाने के लिए है, तो इंटरफ़ेस को लागू करने और विधि स्पष्ट रूप से लागू करने के लिए मूल वर्ग करते हैं:

interface IAnimal 
    { 
     string diary(string notes, int sleephours); 
    } 

    class Dogs:IAnimal 
    {   

virtual public string voice() 
     { 
      string v = "Hao Hao"; return v; 
     } 
     string IAnimal.diary(string notes,int sleephours) 
     { 
      return notes + sleep.ToString() + " hours"; 
     } 

    } 

    class Cats:Dogs 
    { 
     public override string voice() 
     { 
      string v = "Miao Miao"; return v; 
     } 
    } 

आप की डायरी का उपयोग नहीं होगा() बिल्लियों के उदाहरण के माध्यम से विधि।

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