निजी क्षेत्र निजी प्रकार के क्यों हैं, उदाहरण के लिए नहीं?


153

C # (और कई अन्य भाषाओं में) यह एक ही प्रकार के अन्य उदाहरणों के निजी क्षेत्रों तक पहुँचने के लिए पूरी तरह से वैध है। उदाहरण के लिए:

public class Foo
{
    private bool aBool;

    public void DoBar(Foo anotherFoo)
    {
        if (anotherFoo.aBool) ...
    }
}

जैसा कि C # विनिर्देश (अनुभाग 3.5.1, 3.5.2) बताता है कि निजी क्षेत्रों तक पहुंच एक प्रकार पर है, उदाहरण के लिए नहीं। मैं एक सहयोगी के साथ इस बारे में चर्चा कर रहा हूं और हम एक कारण के साथ आने की कोशिश कर रहे हैं कि यह इस तरह से काम क्यों करता है (एक ही उदाहरण के लिए उपयोग को प्रतिबंधित करने के बजाय)।

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


18
विकल्प के लिए क्या लाभ हैं?
जॉन स्कीट

19
यह सच है कि यह वास्तविक दुनिया को बहुत अच्छी तरह से प्रदर्शित नहीं करता है। आखिरकार, सिर्फ इसलिए कि मेरी कार रिपोर्ट कर सकती है कि उसने कितनी गैस छोड़ी है, इसका मतलब यह नहीं है कि मेरी कार को यह बताने में सक्षम होना चाहिए कि कितनी कार हर जगह छोड़ दी गई है। तो, हां, मैं सैद्धांतिक रूप से "निजी उदाहरण" का उपयोग देख सकता हूं। मुझे लगता है कि मैं वास्तव में इसका उपयोग कभी नहीं करूंगा, क्योंकि मुझे चिंता होगी कि 99% मामलों में, मैं वास्तव में एक और उदाहरण चाहता हूं कि उस चर तक पहुंच हो।
एक्विनास

2
@Jon तथाकथित 'लाभ' के लिए जो स्थिति ली गई, वह यह है कि वर्गों को किसी अन्य उदाहरण की आंतरिक स्थिति का पता नहीं होना चाहिए - इस तथ्य की परवाह किए बिना कि यह एक ही प्रकार है। प्रति लाभ नहीं, लेकिन शायद एक बहुत अच्छा कारण है एक को दूसरे पर चुनने का और यही हम यह जानने की कोशिश कर रहे हैं
अमीरके

4
तुम हमेशा गेटर / सेटर बंद की एक जोड़ी, निर्माता में initialised में चर कर सकते हैं, जो अगर असफल हो जायेगी इस एक ही रूप में यह initialisation के दौरान किया गया ... है
मार्टिन Sojka

8
Scala उदाहरण के लिए निजी सदस्यों को प्रदान करता है - साथ ही जावा, C # और कई अन्य भाषाओं में कई अन्य पहुँच स्तर नहीं पाए जाते हैं। यह पूरी तरह से वैध सवाल है।
ब्रूनो रीस

जवाबों:


73

मुझे लगता है कि एक कारण यह इस तरह से काम करता है, क्योंकि संकलन समय पर पहुंच संशोधक काम करते हैं । इस प्रकार, यह निर्धारित करना कि दी गई वस्तु भी है या नहीं, वर्तमान वस्तु भी आसान नहीं है। उदाहरण के लिए, इस कोड पर विचार करें:

public class Foo
{
    private int bar;

    public void Baz(Foo other)
    {
        other.bar = 2;
    }

    public void Boo()
    {
        Baz(this);
    }
}

क्या संकलक जरूरी समझ सकता है कि otherवास्तव में है this? सभी मामलों में नहीं। कोई यह तर्क दे सकता है कि इसे तब संकलित नहीं किया जाना चाहिए, लेकिन इसका मतलब है कि हमारे पास एक कोड पथ है जहां सही उदाहरण का एक निजी उदाहरण सदस्य पहुंच योग्य नहीं है, जो मुझे लगता है कि और भी बुरा है।

केवल आवश्यकता होती वस्तु स्तरीय दृश्यता सुनिश्चित है कि समस्या विनयशील है प्रकार स्तरीय बजाय, साथ ही एक स्थिति की तरह ऐसा लगता है कि बनाने चाहिए काम वास्तव में काम करते हैं।

EDIT : Danilel Hilgarth का कहना है कि यह तर्क पीछे की ओर है, इसमें योग्यता है। भाषा डिजाइनर अपनी इच्छित भाषा बना सकते हैं, और संकलक लेखकों को इसके अनुरूप होना चाहिए। यह कहा जा रहा है कि, भाषा डिजाइनरों के पास कुछ लेखकों को अपना काम करने में आसानी होती है। (इस मामले में हालांकि, यह लोगों का तर्क है कि निजी सदस्यों तो सकता है आसान पर्याप्त है केवल द्वारा ही पहुंचा जा this(अनुमान से या स्पष्ट))।

हालाँकि, मेरा मानना ​​है कि इस मुद्दे को और अधिक भ्रमित करने की आवश्यकता है क्योंकि यह होना चाहिए। यदि उपर्युक्त कोड काम नहीं करता है, तो अधिकांश उपयोगकर्ता (स्वयं शामिल) इसे अनावश्यक रूप से सीमित करेंगे: आखिरकार, यह मेरा डेटा है जिसे मैं एक्सेस करने की कोशिश कर रहा हूं! मुझे क्यों गुजरना चाहिए this?

संक्षेप में, मुझे लगता है कि मैंने इस मामले को संकलक के लिए "मुश्किल" होने से रोक दिया है। वास्तव में मेरा मतलब यह है कि ऊपर की स्थिति ऐसी है कि डिजाइनर काम करना पसंद करेंगे।


33
IMHO, यह तर्क गलत तरीका है। संकलक भाषा के नियमों को लागू करता है। यह उन्हें नहीं बनाता है। दूसरे शब्दों में, यदि निजी सदस्य "उदाहरण निजी" और "निजी प्रकार" नहीं थे, तो संकलक को अन्य तरीकों से लागू किया गया होगा, उदाहरण के लिए केवल अनुमति this.bar = 2लेकिन नहीं other.bar = 2, क्योंकि otherएक अलग उदाहरण हो सकता है।
डैनियल हिल्गारथ

@ डैनियल यह एक अच्छा बिंदु है, लेकिन जैसा कि मैंने उल्लेख किया है, मुझे लगता है कि प्रतिबंध कक्षा स्तर की दृश्यता होने से भी बदतर होगा।
dlev

3
@ ड्वेल: मैंने इस बारे में कुछ नहीं कहा कि मुझे लगता है कि "उदाहरण निजी" सदस्य अच्छी बात है। :-) मैं सिर्फ यह बताना चाहता था कि आप तर्क दे रहे हैं कि तकनीकी कार्यान्वयन भाषा के नियमों को निर्धारित करता है और मेरी राय में, यह तर्क सही नहीं है।
डैनियल हिल्गारथ

2
@ डैनियल पॉइंट लिया। मुझे अभी भी लगता है कि यह एक वैध विचार है, हालांकि आप निश्चित रूप से सही हैं कि अंततः भाषा डिजाइनर यह पता लगाते हैं कि वे क्या चाहते हैं, और संकलक लेखक इसके अनुरूप हैं।
dlev

2
मुझे नहीं लगता कि संकलक-तर्क रखता है। इसके आसपास की भाषाएँ हैं जो केवल उदाहरण के लिए-रूबी (जैसे रूबी) की अनुमति देती हैं और उदाहरण के लिए निजी और वर्ग-निजी को पसंद करती हैं (जैसे एफिल)। कंपाइलर पीढ़ी इन भाषाओं के लिए अधिक कठिन या आसान नहीं थी। अधिक जानकारी के लिए, थ्रेड के नीचे मेरा उत्तर भी देखें।
हाबिल

61

क्योंकि C # और समान भाषाओं में उपयोग किए जाने वाले एन्कैप्सुलेशन का उद्देश्य कोड के विभिन्न टुकड़ों (C # और जावा में कक्षाएं) की पारस्परिक निर्भरता को कम करना है, न कि स्मृति में विभिन्न वस्तुओं को।

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

हालांकि, एनकैप्सुलेशन के बारे में यह सभी सिद्धांत जैसे ही कोई व्यक्ति गुण बनाता है (या जावा में जोड़े सेट / प्राप्त करता है) और सभी क्षेत्रों को सीधे उजागर करता है, जो वर्गों को युग्मित करता है जैसे कि वे वैसे भी खेतों तक पहुंच रहे थे।

* एनकैप्सुलेशन के प्रकार पर स्पष्टीकरण के लिए, हाबिल का उत्कृष्ट उत्तर देखें।


3
मुझे नहीं लगता कि एक बार get/setतरीके प्रदान किए जाने के बाद यह विफल हो जाता है । एक्सेसर विधियां अभी भी एक अमूर्त बनाए रखती हैं (उपयोगकर्ता को यह जानने की आवश्यकता नहीं है कि इसके पीछे एक क्षेत्र है, या संपत्ति के पीछे कौन सा क्षेत्र हो सकता है)। उदाहरण के लिए, यदि हम एक Complexवर्ग लिख रहे हैं, तो हम ध्रुवीय निर्देशांक प्राप्त / सेट करने के लिए गुणों को उजागर कर सकते हैं, और कार्टेशियन निर्देशांक के लिए एक और प्राप्त / सेट करते हैं। जो एक वर्ग नीचे उपयोग करता है वह उपयोगकर्ता के लिए अज्ञात है (यह पूरी तरह से अलग भी हो सकता है)।
केन वेन वांडरलाइंड

5
@Ken: यदि आप इसे उजागर किए जाने पर भी विचार किए बिना हर एक क्षेत्र के लिए एक संपत्ति प्रदान करते हैं तो यह विफल हो जाता है।
गोरान जोविक

@ गोरान हालांकि मैं सहमत हूं कि यह आदर्श नहीं होगा, यह अभी भी पूरी तरह से विफल नहीं है क्योंकि गेट / सेट एक्सेसर्स आपको अतिरिक्त तर्क जोड़ने की अनुमति देते हैं यदि अंतर्निहित फ़ील्ड उदाहरण के लिए बदलते हैं।
फोर्ब्स लिंडसे

1
"क्योंकि एन्कैप्सुलेशन का उद्देश्य कोड के विभिन्न टुकड़ों की पारस्परिक निर्भरता को कम करना है" >> नहीं। एनकैप्सुलेशन का मतलब उदाहरण-एनकैप्सुलेशन भी हो सकता है, यह भाषा या स्कूल-ऑफ़-थिंक पर निर्भर करता है। ऊ, बर्ट्रेंड मेयर पर सबसे निश्चित आवाज़ों में से एक, इसे इसके लिए डिफ़ॉल्ट भी मानता है private। यदि आप चाहें, तो आप चीजों पर मेरे विचार के लिए मेरे जवाब की जांच कर सकते हैं;
एबेल

@ अविश्वास: मैंने कक्षा के इनकैप्सुलेशन के साथ भाषाओं पर अपना उत्तर आधारित किया क्योंकि ओपी ने उनमें से एक के बारे में पूछा, और स्पष्ट रूप से क्योंकि मैं उन्हें जानता हूं। सुधार के लिए धन्यवाद और नई रोचक जानकारी के लिए!
गोरान जोविक

49

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

पुराने दिनों में

80 के दशक में स्मॉलटाक के बीच और 90 के दशक के मध्य में ऑब्जेक्ट-ओरिएंटेशन की अवधारणा परिपक्व हो गई। सूचना छिपाना, मूल रूप से केवल OO के लिए उपलब्ध एक अवधारणा के रूप में नहीं सोचा गया था (1978 में पहली बार उल्लेख किया गया है), स्मॉलटाक में पेश किया गया था क्योंकि एक वर्ग के सभी डेटा (फ़ील्ड) निजी हैं, सभी विधियाँ सार्वजनिक हैं। 90 के दशक में OO के कई नए विकासों के दौरान, बर्ट्रेंड मेयर ने अपनी ऐतिहासिक पुस्तक ऑब्जेक्ट ओरिएंटेड सॉफ्टवेयर कंस्ट्रक्शन (OOSC) में OO की बहुत सी अवधारणाओं को औपचारिक रूप देने की कोशिश की, जिसके बाद से OO अवधारणाओं और भाषा डिजाइन पर एक (लगभग) निश्चित संदर्भ माना जाता है ।

निजी दृश्यता के मामले में

मेयर के अनुसार एक विधि को वर्गों के एक निर्धारित सेट के लिए उपलब्ध कराया जाना चाहिए (पृष्ठ 192-193)। यह जाहिर तौर पर सूचना छुपाने की एक बहुत बड़ी ग्रैन्युलैरिटी देता है, निम्न सुविधा क्लासए और क्लासबी और उनके सभी वंशजों के लिए उपलब्ध है:

feature {classA, classB}
   methodName

मामले में privateवह निम्नलिखित कहता है: स्पष्ट रूप से एक प्रकार की घोषणा के बिना अपनी ही कक्षा में, आप एक योग्य कॉल में उस सुविधा (विधि / क्षेत्र) तक नहीं पहुंच सकते। यानी यदि xएक चर है, x.doSomething()अनुमति नहीं है। अयोग्य प्रवेश की अनुमति है, ज़ाहिर है, कक्षा के अंदर ही।

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

प्रोग्रामिंग भाषाओं में उदाहरण-निजी

मुझे वर्तमान में उपयोग में आने वाली कम से कम दो भाषाओं का पता है जो वर्ग-निजी जानकारी छिपाने के विपरीत, उदाहरण-निजी जानकारी को छिपाने का उपयोग करती हैं। एक है एफिल, मेयर द्वारा डिजाइन की गई एक भाषा है, जो OO को उसके चरम चरम पर ले जाती है। रूबी, आजकल एक सामान्य भाषा है। रूबी में, का privateअर्थ है: "इस उदाहरण के लिए निजी"

भाषा डिजाइन के लिए विकल्प

यह सुझाव दिया गया है कि संकलक के लिए उदाहरण-निजी की अनुमति देना कठिन होगा। मुझे ऐसा नहीं लगता है, क्योंकि यह केवल विधियों के लिए योग्य कॉल को अनुमति देने या अस्वीकार करने के लिए अपेक्षाकृत सरल है। यदि किसी निजी विधि के लिए, doSomething()अनुमति दी गई है और x.doSomething()नहीं है, तो एक भाषा डिजाइनर ने प्रभावी रूप से केवल निजी तरीकों और क्षेत्रों के लिए आवृत्ति-पहुंच को परिभाषित किया है।

तकनीकी दृष्टिकोण से, कोई एक रास्ता या दूसरा चुनने का कोई कारण नहीं है (esp। जब यह विचार करते हुए कि एफिल .नेट IL के साथ ऐसा कर सकता है, यहां तक ​​कि कई विरासत के साथ, इस सुविधा को प्रदान करने का कोई अंतर्निहित कारण नहीं है)।

बेशक, यह स्वाद की बात है और जैसा कि दूसरों ने पहले ही उल्लेख किया है, निजी विधियों और क्षेत्रों के वर्ग-स्तरीय दृश्यता की सुविधा के बिना लिखने के लिए काफी कुछ तरीके कठिन हो सकते हैं।

क्यों C # केवल वर्ग एनकैप्सुलेशन की अनुमति देता है और उदाहरण एनकैप्सुलेशन नहीं

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

हालाँकि, C # ने अपनी भाषा डिज़ाइन के लिए C ++ और Java में सबसे कठिन रूप से देखा है। जबकि एफिल और मोडुला -3 भी तस्वीर में थे, एफिल की कई विशेषताओं को याद करते हुए (कई विरासत) गायब होने के बारे में मेरा मानना ​​है कि उन्होंने निजी एक्सेस संशोधक के लिए जावा और सी ++ के समान मार्ग चुना।

यदि आप वास्तव में जानना चाहते हैं कि आपको एरिक लिपर्ट, क्रिज़ीस्टोफ़ सेल्विना, एंडर्स हेज़ेल्सबर्ग या किसी और को पकड़ने की कोशिश करनी चाहिए जिसने सी # के मानक पर काम किया। दुर्भाग्य से, मुझे एन # सी # प्रोग्रामिंग लैंग्वेज में एक निश्चित नोट नहीं मिला ।


1
यह एक बहुत ही पृष्ठभूमि के साथ एक सुंदर जवाब है, बहुत दिलचस्प है, एक (अपेक्षाकृत) पुराने सवाल का जवाब देने के लिए समय निकालने के लिए धन्यवाद
रिचके

1
@RichK: आपका स्वागत है, बस मैंने बहुत देर से सवाल पकड़ा, लेकिन मुझे कुछ गहराई से जवाब देने के लिए काफी पेचीदा विषय मिला
Abel

COM के तहत, "निजी" का अर्थ "उदाहरण-निजी" है। मुझे लगता है कि यह कुछ माप में था क्योंकि कक्षा की एक परिभाषा Fooप्रभावी रूप से एक इंटरफ़ेस और एक कार्यान्वयन वर्ग का प्रतिनिधित्व करती थी; चूंकि COM में क्लास-ऑब्जेक्ट संदर्भ की अवधारणा नहीं थी - सिर्फ एक इंटरफ़ेस संदर्भ - ऐसा कोई तरीका नहीं था कि कोई वर्ग उस चीज का संदर्भ दे सकता है जिसे उस वर्ग का एक और उदाहरण होने की गारंटी दी गई थी। इस इंटरफ़ेस-आधारित डिज़ाइन ने कुछ चीजों को बोझिल बना दिया, लेकिन इसका मतलब था कि एक वर्ग डिजाइन कर सकता है जो किसी अन्य के लिए एक ही आंतरिक हिस्से को साझा किए बिना प्रतिस्थापन योग्य था।
सुपरकैट

2
बहुत बढ़िया जवाब। ओपी को इस सवाल के जवाब पर विचार करना चाहिए।
गैविन ओसबोर्न

18

यह केवल मेरी राय है, लेकिन व्यावहारिक रूप से, मुझे लगता है कि यदि किसी प्रोग्रामर के पास किसी कक्षा के स्रोत तक पहुंच है, तो आप कक्षा उदाहरण के निजी सदस्यों तक पहुंचने के लिए उन पर यथोचित भरोसा कर सकते हैं। एक प्रोग्रामर को दाहिने हाथ से क्यों बाँधें जब उनके बाएं में आपने पहले ही उन्हें राज्य की चाबी दे दी हो?


13
मैं इस तर्क को नहीं समझता। मान लीजिए कि आप एक ऐसे प्रोग्राम पर काम कर रहे हैं, जहाँ आप एकमात्र डेवलपर हैं और आप केवल वही हैं जो कभी आपके पुस्तकालयों का उपयोग करेगा, क्या आप उस स्थिति में कह रहे हैं कि आप हर किसी को सार्वजनिक करते हैं क्योंकि आपके पास स्रोत कोड तक पहुंच है?
एक्विनास

@ ऑकिनस: यह काफी अलग है। सब कुछ सार्वजनिक करने से भयानक प्रोग्रामिंग प्रथाओं को बढ़ावा मिलेगा। खुद के अन्य उदाहरणों के निजी क्षेत्रों को देखने के लिए एक प्रकार की अनुमति देना बहुत ही संकीर्ण मामला है।
Igby Largeman

2
नहीं, मैं हर सदस्य को सार्वजनिक करने की वकालत नहीं कर रहा हूँ। हेवन्स नहीं! मेरा तर्क है, यदि आप पहले से ही स्रोत में हैं, निजी सदस्यों को देख सकते हैं, उनका उपयोग कैसे किया जाता है, नियोजित सम्मेलनों, आदि, तो उस ज्ञान का उपयोग करने में सक्षम क्यों नहीं हैं?
FishBasketGordo

7
मुझे लगता है कि सोचने का तरीका अभी भी प्रकार के संदर्भ में है। यदि प्रकार के सदस्यों के साथ ठीक से व्यवहार करने के लिए इस प्रकार पर भरोसा नहीं किया जा सकता है, तो क्या हो सकता है? ( आम तौर पर , यह वास्तव में बातचीत को नियंत्रित करने वाला एक प्रोग्रामर होगा, लेकिन कोड-जनरेशन टूल्स के इस युग में, यह मामला नहीं हो सकता है।)
एंथनी पेग्राम

3
मेरा प्रश्न वास्तव में भरोसे का नहीं है, आवश्यकता से अधिक है। ट्रस्ट पूरी तरह से अप्रासंगिक है जब आप प्रतिबिंब का उपयोग निजी चीजों के लिए कर सकते हैं। मैं सोच रहा हूँ क्यों, वैचारिक रूप से, आप निजी लोगों तक पहुँच सकते हैं। मैंने माना कि एक सर्वोत्तम-व्यवहार की स्थिति के बजाय एक तार्किक कारण था।
रिक्टर

13

वास्तव में कारण समानता की जांच, तुलना, क्लोनिंग, ऑपरेटर ओवरलोडिंग है ... उदाहरण के लिए, जटिल संख्याओं पर ऑपरेटर + को लागू करना बहुत मुश्किल होगा।


3
लेकिन जो कुछ भी आप उल्लेख करते हैं, उन्हें एक प्रकार के दूसरे प्रकार के मूल्य को प्राप्त करने की आवश्यकता होती है। मैं यह कहने के साथ बोर्ड पर हूं: क्या आप मेरे निजी राज्य का निरीक्षण करना चाहते हैं? ठीक है, आगे बढ़ो। आप मेरा निजी राज्य स्थापित करना चाहते हैं ? कोई रास्ता नहीं, दोस्त, अपनी खुद की लानत बदलो। :)
एक्विनास 16

2
@aquinas यह उस तरह से काम नहीं करता है। फ़ील्ड्स फ़ील्ड हैं। वे केवल तभी पढ़े जाते हैं, जब उन्हें घोषित किया जाता है readonlyऔर फिर घोषणा के उदाहरण पर भी लागू होता है। जाहिर तौर पर आप यह मान रहे हैं कि इस पर रोक लगाने के लिए एक विशिष्ट संकलक नियम होना चाहिए, लेकिन ऐसा प्रत्येक नियम एक विशेषता है जिसे C # टीम को बाहर निकालना, दस्तावेज़, स्थानीयकरण, परीक्षण, रखरखाव और समर्थन करना है। यदि कोई सम्मोहक लाभ नहीं है तो वे ऐसा क्यों करेंगे?
हारून को

मैं @ सहमत के साथ सहमत हूं: हर नई कल्पना को लागू करने और संकलक को बदलने के साथ एक लागत जुड़ी हुई है। एक सेट परिदृश्य के लिए, एक क्लोन विधि पर विचार करें। निश्चित रूप से, आप इसे निजी कंस्ट्रक्टर के साथ महसूस करना चाह सकते हैं, लेकिन शायद कुछ परिदृश्यों में यह संभव / उचित नहीं है।
लोरेंजो डेमेटे

1
सी # टीम? मैं किसी भी भाषा में संभावित सैद्धांतिक भाषा परिवर्तनों पर बहस कर रहा हूं। "अगर कोई सम्मोहक लाभ नहीं है ..." मुझे लगता है कि कोई लाभ हो सकता है। किसी भी संकलक गारंटी के साथ की तरह , किसी को यह गारंटी देना उपयोगी हो सकता है कि एक वर्ग केवल अपने राज्य को संशोधित करता है।
एक्विनास

@aquinas: सुविधाएँ लागू हो जाती हैं क्योंकि वे कई या अधिकांश उपयोगकर्ताओं के लिए उपयोगी होती हैं - इसलिए नहीं कि वे कुछ अलग-थलग मामलों में उपयोगी हो सकती हैं।
आरोह

9

सबसे पहले, निजी स्थिर सदस्यों का क्या होगा? क्या उन्हें केवल स्थैतिक विधियों द्वारा ही पहुँचा जा सकता है आप निश्चित रूप से ऐसा नहीं चाहेंगे, क्योंकि तब आप अपने constएस तक पहुँचने में सक्षम नहीं होंगे ।

अपने स्पष्ट प्रश्न के अनुसार, उस मामले पर विचार करें StringBuilder, जिसे स्वयं के उदाहरणों से जुड़ी हुई सूची के रूप में लागू किया गया है:

public class StringBuilder
{
    private string chunk;
    private StringBuilder nextChunk;
}

यदि आप अपने स्वयं के वर्ग के अन्य उदाहरणों के निजी सदस्यों तक नहीं पहुंच सकते हैं, तो आपको ToStringइस तरह से लागू करना होगा:

public override string ToString()
{
    return chunk + nextChunk.ToString();
}

यह काम करेगा, लेकिन यह ओ (एन ^ 2) है - बहुत कुशल नहीं है। वास्तव में, यह शायद StringBuilderपहली जगह में एक वर्ग होने के पूरे उद्देश्य को हरा देता है। यदि आप अपने स्वयं के वर्ग के अन्य उदाहरणों के निजी सदस्यों तक पहुंच सकते हैं , तो आप ToStringउचित लंबाई की एक स्ट्रिंग बनाकर कार्यान्वित कर सकते हैं और फिर प्रत्येक कबाड़ की एक असुरक्षित प्रतिलिपि स्ट्रिंग में इसकी उपयुक्त जगह पर कर सकते हैं:

public override string ToString()
{
    string ret = string.FastAllocateString(Length);
    StringBuilder next = this;

    unsafe
    {
        fixed (char *dest = ret)
            while (next != null)
            {
                fixed (char *src = next.chunk)
                    string.wstrcpy(dest, src, next.chunk.Length);
                next = next.nextChunk;
            }
    }
    return ret;
}

यह कार्यान्वयन O (n) है, जो इसे बहुत तेज़ बनाता है, और यह तभी संभव है जब आपकी कक्षा के अन्य उदाहरणों के निजी सदस्यों तक आपकी पहुँच हो


हाँ, लेकिन उसके आसपास अन्य तरीके नहीं हैं, जैसे कि कुछ क्षेत्रों को आंतरिक के रूप में उजागर करना?
माइककूल

2
@ माइक: किसी फ़ील्ड को एक्सपोज़ करना, क्योंकि internalयह कम निजी है! आप अपनी कक्षा के आंतरिक लोगों को इसकी विधानसभा में सब कुछ उजागर करने का प्रयास करेंगे।
गेबे

3

यह कई भाषाओं में पूरी तरह से वैध है (एक के लिए C ++)। पहुँच संशोधक OOP में इनकैप्सुलेशन सिद्धांत से आते हैं। विचार बाहर तक पहुंच को प्रतिबंधित करना है , इस मामले में बाहर अन्य कक्षाएं हैं। उदाहरण के लिए C # में कोई भी नेस्टेड क्लास अभिभावकों के निजी सदस्यों तक भी पहुँच सकता है।

जबकि यह एक भाषा डिजाइनर के लिए एक डिज़ाइन विकल्प है। इस पहुंच का प्रतिबंध संस्थाओं के अलगाव में ज्यादा योगदान दिए बिना कुछ बहुत ही सामान्य परिदृश्यों को जटिल बना सकता है।

इसी तरह की चर्चा यहाँ है


1

मुझे नहीं लगता कि ऐसा कोई कारण है कि हम गोपनीयता का एक और स्तर नहीं जोड़ सकते, जहां डेटा प्रत्येक उदाहरण के लिए निजी है। वास्तव में, यह भी भाषा को पूर्णता की एक अच्छी भावना प्रदान कर सकता है।

लेकिन वास्तविक व्यवहार में, मुझे संदेह है कि यह वास्तव में उपयोगी होगा। जैसा कि आपने बताया, हमारा सामान्य निजी-नेस यह समता की जाँच जैसी चीज़ों के लिए उपयोगी है, साथ ही साथ अन्य प्रकार के कई उदाहरणों को शामिल करते हुए अन्य संचालन। हालाँकि, मुझे डेटा एब्सट्रैक्शन को बनाए रखने के बारे में आपकी बात भी पसंद है, क्योंकि यह OOP का एक महत्वपूर्ण बिंदु है।

मुझे लगता है कि चारों ओर, इस तरह से पहुंच को प्रतिबंधित करने की क्षमता प्रदान करना OOP को जोड़ने के लिए एक अच्छी सुविधा हो सकती है। क्या यह वास्तव में उपयोगी है? मैं कहूंगा कि नहीं, क्योंकि एक वर्ग को अपने स्वयं के कोड पर भरोसा करने में सक्षम होना चाहिए। चूँकि वह वर्ग ही एकमात्र ऐसी चीज़ है जो निजी सदस्यों तक पहुँच सकती है, इसलिए दूसरी कक्षा के उदाहरण के साथ काम करते समय डेटा एब्स्ट्रैक्शन की आवश्यकता नहीं है।

बेशक, आप हमेशा अपना कोड लिख सकते हैं जैसे कि निजी उदाहरणों पर लागू होता है। get/setडेटा तक पहुंचने / बदलने के लिए सामान्य तरीकों का उपयोग करें। यदि कक्षा आंतरिक परिवर्तनों के अधीन हो सकती है, तो संभवतः यह कोड को अधिक प्रबंधनीय बना देगा।


0

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

BTW .... यही समस्या "संरक्षित" सदस्यों पर भी लागू होती है। :(

मैंने उस प्रोग्रामिंग प्रतिमान को कभी भी पूरी तरह से स्वीकार नहीं किया क्योंकि यह अभी भी मुद्दों और जोखिमों के एक पूरे सूट के साथ आता है जो कि अधिकांश प्रोग्रामर पूरी तरह से समझ नहीं पाते हैं जब तक कि इस समस्या जैसे मुद्दे उठते हैं और लोगों को भ्रमित करते हैं और निजी सदस्यों के होने के पूरे कारण को टाल देते हैं।

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


-1

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

धीरे-धीरे बोलते हुए, मुझे व्यक्तिगत रूप से लगता है कि बेस क्लास से ली गई राइटिंग क्लास आपको उसी तरह की कार्यक्षमता प्रदान करती है, जिसका वर्णन आप 'उदाहरण के लिए निजी डेटा' के साथ कर रहे हैं। इसके बजाय, आपके पास 'अद्वितीय' प्रकार के अनुसार बस एक नई कक्षा परिभाषा है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.