2012-06-01 18 views
11

क्या सी # बेस क्लास केवल पुस्तकालय असेंबली के भीतर सुलभ हो सकता है, जिसमें इसे संकलित किया गया है, जबकि अन्य सबक्लास जो इसे प्राप्त करते हैं?सी # निजी (छुपा) बेस क्लास

उदाहरण के लिए:

using System.IO; 

class BaseOutput: Stream   // Hidden base class 
{ 
    protected BaseOutput(Stream o) 
    { ... } 

    ...lots of common methods... 
} 

public class MyOutput: BaseOutput // Public subclass 
{ 
    public BaseOutput(Stream o): 
     base(o) 
    { ... } 

    public override int Write(int b) 
    { ... } 
} 

यहाँ मैं पसंद BaseOutput वर्ग मेरे पुस्तकालय के ग्राहकों के लिए दुर्गम होने के लिए, लेकिन उपवर्ग MyOutput पूरी तरह से सार्वजनिक होने की अनुमति होगी। मुझे पता है कि सी # बेस क्लास को उप-वर्गों की तुलना में अधिक प्रतिबंधक पहुंच की अनुमति नहीं देता है, लेकिन क्या एक ही प्रभाव प्राप्त करने का कोई अन्य कानूनी तरीका है?

अद्यतन

इस विशेष पुस्तकालय के लिए मेरे समाधान आधार वर्ग public और abstract बनाने के लिए, और के साथ दस्तावेज़ के लिए "इस आधार सीधे वर्ग का प्रयोग न करें" है। मैं बेस क्लास internal का कन्स्ट्रक्टर भी बना देता हूं, जो बाहरी क्लाइंट को वर्ग का उपयोग करने या विरासत में प्रभावी ढंग से रोकता है।

(क्योंकि अन्य हे-ओ भाषाओं मुझे आधार वर्ग को छुपाया है चलो यह शर्म की बात है।)

+0

आप 'बेसऑटपुट' आंतरिक का निर्माता क्यों नहीं बनाते हैं, इसलिए कोई बाहरी कोड इससे प्राप्त नहीं हो सकता है? –

+0

@ माइकज़: हाँ, मैंने यही किया है, ऊपर दिए गए अपडेट को देखें। –

+0

आंतरिक कन्स्ट्रक्टर के साथ सार्वजनिक वर्ग शायद एक बेहतर विकल्प (मेरे उत्तर में नमूना) –

उत्तर

12
नहीं

दुर्भाग्य से। आप एक सार्वजनिक कक्षा को एक आंतरिक या निजी वर्ग से प्राप्त नहीं कर सकते हैं।

आपको या तो बेस क्लास का पर्दाफाश करने की आवश्यकता है, या आपको अपने सभी समान वर्गों के लिए सभी विधियों की घोषणा करने की आवश्यकता है। यदि आप मार्ग पर जाते हैं जहां आप सभी विधियों को दोबारा घोषित करते हैं, तो संभवतः एक सहायक वर्ग बनाने के लिए उपयोगी होता है, जिसमें उनके वास्तविक कार्यान्वयन होते हैं। फिर भी यह बॉयलरप्लेट का थोड़ा सा है।

+0

बहुत बुरा। जावा मुझे ऐसा करने देता है। –

+1

क्यों "दुर्भाग्य से"? – stakx

+4

क्योंकि यह कभी-कभी मुझे बॉयलरप्लेट का थोड़ा सा बचा लेता। उदाहरण के लिए कई कक्षाओं में एक ही इंटरफेस को लागू करते समय। – CodesInChaos

5

एक फेकाडे जैसे पैटर्न पर विचार करें। यही वह है जिसके लिए वे हैं। मुझे नहीं लगता कि आप सीधे विरासत के साथ जो कुछ हासिल कर सकते हैं उसे हासिल कर सकते हैं।

+0

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

+1

वास्तव में, किसी को वैसे भी विरासत पर संरचना का पक्ष लेना चाहिए (http: //en.wikipedia।संगठन/विकी/composition_over_inheritance) – jeroenh

+0

@ जेरोहेन - यह मेरे बिंदु के बिल्कुल विपरीत है। मैं बेस क्लास को * अधिकांश * विधियों और चरों को कार्यान्वित करना चाहता हूं, और मैं चाहता हूं कि प्रत्येक व्युत्पन्न उपclass * जितना संभव हो सके * लागू करें। –

1
क्या "आम तरीकों में से बहुत कुछ" पर निर्भर करता है

कर रहे हैं आप आंतरिक विस्तार के तरीकों के साथ इसके बारे में कुछ प्राप्त हो सकता है:

internal static class MyStreamExtensions 
{ 
    internal static int UsefulOne(this Stream stream) 
    { 
    return 42; 
    } 
} 

एक और दृष्टिकोण निर्माता उस वर्ग से अनजाने में व्युत्पत्ति को रोकने के लिए आंतरिक बनाने के लिए है:

public class BaseOutput: Stream 
{ 
    internal BaseOutput(Stream o) 
    { ... } 

    ...lots of common methods... 
} 

यह पदानुक्रम में "वास्तव में दिखाई देने वाली" मध्यवर्ती कक्षा की तुलना में कोड को और अधिक समझने योग्य बना देगा।