2012-05-05 11 views
6

मैं सी # प्रोग्रामर डी भाषा में नया हूं। मैं डी प्रोग्रामिंग भाषा में ओओपी के साथ भ्रमित करने के लिए थोड़ा सा हूँ।क्यों संरक्षित संशोधक के साथ एक समारोह ओवरराइड किया जा सकता है और हर जगह सुलभ हो सकता है?

यह मानते हुए कि मैं निम्नलिखित वर्ग है:

public class A { 
    protected void foo() { 
     writefln("A.foo() called."); 
    } 
}; 

public class B : A { 
    public override void foo() { 
     writefln("B.foo() called."); 
    } 
}; 

protected संशोधक मतलब यह है कि मैं सिर्फ विरासत में मिला वर्ग पर .foo() विधि का उपयोग कर सकते, तो क्यों इस डी कार्यक्रम सामान्य रूप से संकलित?

यहाँ सी # नेट के बराबर है:

using System; 

public class A { 
    protected virtual void foo() { 
     Console.WriteLine("a.foo() called."); 
    } 
}; 

public class B : A { 
    public override void foo() { 
     Console.WriteLine("b.foo() called."); 
    } 
}; 

public class MainClass { 
    public static void Main(string[] args) { 
     A a = new A(); 
     B b = new B();  
     a.foo(); 
     b.foo(); 
    } 
}; 

यह ऐसा नहीं compiles और दिए गए निम्न त्रुटि संदेश (के रूप में मैं उम्मीद):

test.cs (10 , 30): त्रुटि CS0507: B.foo()': cannot change access modifiers when overriding सुरक्षित 'विरासत में मिला सदस्य `A.foo()'

कोई इस डी व्यवहार की व्याख्या कर सकते हैं? अग्रिम में धन्यवाद।

+2

आप उलझन में क्यों हैं? सी # और डी सिर्फ अलग-अलग भाषाएं हैं, इसलिए वे चीजों को अलग-अलग करते हैं। पहली बार, दोनों दृष्टिकोण मेरे लिए कुछ समझ में आते हैं, इसलिए यह तय करने के लिए भाषा डिजाइनरों पर निर्भर है कि किस तरह से जाना है। – svick

+0

हम, क्योंकि मुझे यह ध्यान में था कि एक ऑब्जेक्ट उन्मुख प्रोग्रामिंग भाषा का एक्सेस-मॉडिफायर उसी तरह संचालित होता है। – Jack

+0

डाउनवॉट्स - कृपया समझा सकते हैं? – Jack

उत्तर

16

ओवरराइड को रोकने में कोई उद्देश्य नहीं है। व्युत्पन्न वर्ग एक मामूली अग्रेषण समारोह लागू कर सकता है जो पहुंच की अनुमति देता है। पर विचार करें:

public class A { 
    protected void foo() { 
     writefln("A.foo() called."); 
    } 
}; 

public class B : A { 
    protected override void foo() { // OK 
     writefln("B.foo() called."); 
    } 
    public void call_foo() { 
     foo(); // But I allowed public access anyway! 
    } 
}; 

इस प्रकार, भले ही मैंने foo के पहुंच स्तर को फिर से परिभाषित नहीं किया, मैं अभी भी यह सार्वजनिक उपयोग की अनुमति दी और वहाँ कुछ भी नहीं आप इसे के बारे में क्या कर सकते हैं। पुनर्वितरण की अनुमति देना बस आसान है।

+0

हम, फिर यह 'डी' डिजाइनर है। 'सी # .NET' भाषा में, संभव नहीं है 'call_foo()' विधि की तरह कुछ लिखें। यह एक त्रुटि CS0122 दिया गया: एएफयू() 'इसके सुरक्षा स्तर के कारण पहुंच योग्य नहीं है।' आपके उत्तर के लिए धन्यवाद। :) – Jack

+0

@ जैक: क्या, सी # में आप एक सार्वजनिक विधि नहीं लिख सकते हैं जो संरक्षित विधि कहता है? – Puppy

+0

नहीं। मेरे लिए काम नहीं करता है, मैंने सी # -मोनो पर परीक्षण किया है और यह उपरोक्त त्रुटि संदेश दिया गया है। – Jack

5

इस मैचों में जावा के व्यवहार से मेल का व्यवहार। एक व्युत्पन्न वर्ग अपने कार्य को एक पहुंच स्तर प्रदान कर सकता है जो बेस क्लास में फ़ंक्शन पर एक से कम प्रतिबंधित है लेकिन एक ऐसा नहीं है जो अधिक प्रतिबंधित है। इसलिए, protected फ़ंक्शन को protected या public के रूप में ओवरराइड किया जा सकता है, लेकिन इसे private के रूप में ओवरराइड नहीं किया जा सकता है, और public फ़ंक्शन को केवल public के रूप में ओवरराइड किया जा सकता है।

मुझे नहीं पता कि क्यों सी # protected प्रतिबंधित करेगा जैसे कि आप public फ़ंक्शन के साथ इसे ओवरराइड नहीं कर सके। किसी ऐसे व्यक्ति के रूप में जिसने सी ++, डी, और जावा में बहुत अच्छा प्रोग्राम किया है लेकिन सी # में बहुत कम है, सी # की पसंद यहां मुझे बहुत कम समझ में आता है। सी ++, डी, और जावा सभी इसे अनुमति देते हैं।

7

क्योंकि सवाल के कुछ महान जवाब हैं "यह क्यों संभव है?" मुझे लगता है कि सी # स्पष्टीकरण का हकदार है क्यों यह संभव नहीं है: यह एक भाषा डिजाइन के "दर्शन" के बारे में है, और इसे "आइस-ए" बनाम "है-ए" विचारों के संघर्ष के लिए उबलाया जा सकता है।

सी ++ सभी "है-ए" सोच के बारे में है, इसमें से कुछ को डी और जावा में भेज दिया गया था। बी में विधि foo है और यह संकलक और प्रोग्रामर दोनों के लिए सबसे महत्वपूर्ण है - बी क्या नहीं है। सी ++ में एक विधि को निजी (या निजी के रूप में कक्षा उत्तराधिकारी) के रूप में फिर से शुरू करना संभव है जिसका अर्थ है कि ए का सदस्य बी

सी # "आइस-ए" अवधारणा के बारे में कट्टर है। इसलिए क्योंकि यहां बी वास्तव में ए है, बी में सबकुछ ए में होना चाहिए। न तो कंपाइलर और न ही प्रोग्रामर को बदलावों के बारे में चिंता करने की ज़रूरत है, क्योंकि कोई भी परिवर्तन संभव नहीं है।बी हमेशा ए

"is-a" दर्शन पहले से संरक्षित सदस्य को प्रचारित करने से सी # कार्यक्रम को प्रतिबंधित करता है, भले ही यह सार्वजनिक रैपर के माध्यम से ऐसा करने के लिए तुच्छ है। यह थोड़ा समझ में आता है और यहां केवल एक छोटी सी असुविधा है - लेकिन यह भाषा दर्शन को लगातार बनाए रखने में एक बड़ा सौदा है।

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