निजी क्षेत्र क्यों हैं, पर्याप्त सुरक्षा नहीं है?


265

क्या privateक्लास फ़ील्ड्स / गुणों / विशेषताओं की दृश्यता उपयोगी है? ओओपी में, जल्दी या बाद में, आप एक वर्ग का उपवर्ग बनाने जा रहे हैं और उस मामले में, यह समझना अच्छा है और कार्यान्वयन को पूरी तरह से संशोधित करने में सक्षम है।

जब मैं एक वर्ग को उपवर्ग में करता हूं, तो पहली चीजों में से एक को privateतरीकों का एक गुच्छा बदलना है protected। हालाँकि, बाहरी दुनिया से विवरण छिपाना महत्वपूर्ण है-इसलिए हमें ज़रूरत है protectedऔर बस नहीं public

मेरे सवाल यह है: आप एक महत्वपूर्ण उपयोग के मामले जहां के बारे में जानते हैं privateके बजाय protectedएक अच्छा उपकरण है, या दो विकल्प "हैं protectedऔर public" OOP भाषाओं के लिए पर्याप्त हो सकता है?



236
डाउनवोटर्स के लिए: जबकि मैं भी ओपी के परिसर से दृढ़ता से असहमत हूं, मैं इस सवाल को बढ़ा रहा हूं क्योंकि यह पूरी तरह से सुसंगत है और जवाब देने के लायक है। हां, ओपी को यह बताने की आवश्यकता है कि यह गलत क्यों है, लेकिन ऐसा करने का तरीका एक उत्तर लिखना है (या मौजूदा उत्तरों को संपादित करने का सुझाव देना है), केवल इसलिए नहीं कि वह इसे अभी तक खुद के लिए नहीं समझ पाया है।
Ixrec

18
व्युत्पन्न वर्ग बाहरी दुनिया का हिस्सा हैं।
कोडइन्चोस

20
यह मत भूलो कि संरक्षित का मतलब यह नहीं है कि पहुंच विरासत वंशानुक्रम पर बंद है। जावा में, यह पैकेज स्तर तक पहुँच भी प्रदान करता है।
berry120 11:11

8
मेरे प्रोफेसर कहते थे कि "ऐसी चीजें हैं जो मैं अपने बच्चों को नहीं बताऊंगा। मैं अपने निजी क्षेत्र।"
18

जवाबों:


225

क्योंकि जैसा कि आप कहते हैं, protectedअभी भी आपको "कार्यान्वयन को पूरी तरह से संशोधित करने" की क्षमता के साथ छोड़ देता है। यह वास्तव में वर्ग के अंदर किसी भी चीज़ की रक्षा नहीं करता है।

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

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

संयोग से, जबकि "ओओपी में, जल्दी या बाद में, आप एक वर्ग का उपवर्ग बनाने जा रहे हैं" तकनीकी रूप से सच है, आपका तर्क बहुत मजबूत धारणा बना रहा है कि "जितनी जल्दी या बाद में, आप एक उपवर्ग बनाने जा रहे हैं हर वर्ग "जो लगभग निश्चित रूप से ऐसा नहीं है।


11
अगर मैं कर सकता था तो मैं आपको +1 से अधिक टॉस करूंगा, क्योंकि यह पहली बार है privateजब वास्तव में मेरे लिए यह समझ में आया है। काम के परिप्रेक्ष्य को अधिक बार उपयोग करने की आवश्यकता होती है, अन्यथा किसी को भी (सी-लाइक) "पूर्ण नियंत्रण, पूर्ण जिम्मेदारी" कोडिंग मानसिकता के रूप में चिह्नित कर सकता है क्योंकि यह "मुझे खुद से बचाता है"। ध्यान दें कि मैंने अभी भी privateपहले इस्तेमाल किया था, मुझे हमेशा अच्छा दस्तावेज लगा और एक नामकरण सम्मेलन जैसा _fooकि आपको संकेत मिलता है कि शायद इसके साथ खिलवाड़ नहीं होना चाहिए अगर यह बेहतर नहीं था। नियत रूप से कहने में सक्षम होने के नाते "कुछ भी नहीं टूटेगा" एक वैध, private-एक विशेषता है।
abluejelly

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

9
@ AdamLibuša हालांकि यह बहुत बड़ी बात है यदि आपका कोड सार्वजनिक है, यह तब भी लागू होता है जब आप सभी वर्ग के ग्राहकों के लेखक हों। समस्या बस कुछ रिफ्लेक्टर से बदलती है जो कुछ रिफ्लेक्टर से थकाऊ और त्रुटि-प्रवण होना असंभव है। अनुकूलन वास्तव में मेरे अनुभव में इन रिफ्लेक्टरों के लिए कम से कम सामान्य कारण है (हालांकि मैं मुख्य रूप से जावास्क्रिप्ट करता हूं), आमतौर पर यह एक बग की तरह अधिक होता है जो एक मौलिक कार्यान्वयन दोष को उजागर करता है जिसे प्राप्त करने के लिए विभिन्न आंतरिक बिट्स की निर्भरता / कॉल ग्राफ के पुनर्गठन की आवश्यकता होती है वास्तव में एक मजबूत तय।
Ixrec

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

1
मैं आपको +1 से अधिक टॉस करूँगा यदि मैं => यह कह सकता हूं कि हम बाउंटी @abluejelly को कॉल करते हैं
थॉमस अय्यूब

256

OOP में, जल्दी या बाद में, आप एक वर्ग का उपवर्ग बनाने जा रहे हैं

ये गलत है। प्रत्येक वर्ग को उपवर्गित नहीं माना जाता है और कुछ वैधानिक रूप से टाइप की गई OOP भाषाओं में भी इसे रोकने की विशेषताएं होती हैं, जैसे, final(Java और C ++) या sealed(C #)।

यह समझने में अच्छा है और कार्यान्वयन को पूरी तरह से संशोधित करने में सक्षम है।

नहीं यह नहीं। यह एक वर्ग के लिए अच्छा है कि वह अपने सार्वजनिक इंटरफ़ेस को स्पष्ट रूप से परिभाषित करने में सक्षम हो और अपने उत्तराधिकारियों को संरक्षित करे, भले ही यह विरासत में मिला हो।

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

या इसे स्कॉट मेयर्स के संदर्भ में रखने के लिए: एक वर्ग के निजी हिस्से कोड की एक परिमित राशि से प्रभावित होते हैं: स्वयं कक्षा का कोड।

सार्वजनिक भाग संभावित रूप से कोड के प्रत्येक बिट से प्रभावित होते हैं, और प्रत्येक बिट कोड को अभी तक लिखा जाना है, जो कि कोड की एक अनंत राशि है।

संरक्षित हिस्से संभावित रूप से हर मौजूदा उपवर्ग से प्रभावित होते हैं, और प्रत्येक उपवर्ग को लिखा जाना बाकी है, जो कोड की एक अनंत राशि भी है।

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


34
"कोड की अनंत राशि से प्रभावित" के सैद्धांतिक परिदृश्य के लिए +1
ब्रोकन_विंडो

13
शायद ध्यान देने योग्य बात यह है कि C # डिज़ाइनरों ने वास्तव में विरासत में मिली विधि को ओवरराइड करने पर रोक लगाने का फैसला किया जब तक कि virtualइस उत्तर में उल्लिखित कारणों के लिए इसे स्पष्ट रूप से चिह्नित नहीं किया गया है।
विलसन

11
या बस रखा: protectedतरीकों के लिए है, डेटा सदस्यों के लिए नहीं।
मैथ्यू एम।

7
मुझे यह अब नहीं मिल रहा है, लेकिन मुझे याद है कि MSE sealed.net की लाइब्रेरी और IIRC के बड़े हिस्सों के बारे में @EricLippert से एक अच्छा लिखित उत्तर पढ़कर वह बाकी को लॉक करना क्यों पसंद करता है। जिस क्षण आप तीसरे पक्ष के उत्तराधिकारियों को आंतरिक मूल्यों को छूने की शुरुआत करने की अनुमति देते हैं, आपको प्रत्येक विधि में सत्यापन / पवित्रता की एक बड़ी मात्रा को जोड़ने की आवश्यकता होती है क्योंकि आप अब वस्तुओं की आंतरिक स्थिति के बारे में किसी भी डिजाइन आक्रमणकारियों पर भरोसा नहीं कर सकते हैं।
डैन नीली

4
@ ThorbjørnRavnAndersen "विकसित होने के दौरान लेकिन जारी नहीं होने पर" - पृथ्वी पर एक वर्ग को कैसे जानना चाहिए? क्या आप वास्तव में एक परीक्षण संस्करण संकलित करना चाहते हैं जो रिलीज़ किए गए संस्करण से अलग है जब आप रिलीज़ संस्करण का परीक्षण भी नहीं कर सकते हैं? टेस्ट को वैसे भी निजी सामान तक पहुंचने की आवश्यकता नहीं होनी चाहिए।
सेबस्टियन रेडल

33

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

निजी क्षेत्र आमतौर पर सुरक्षा प्रदान करने के बारे में होते हैं कि डेटा मूल कोडर के अनुसार होता है। सब कुछ सुरक्षित / सार्वजनिक करें और आप उन प्रक्रियाओं और मान्यता के माध्यम से एक कोच और घोड़ों की सवारी करें।


2
कुछ भी "के माध्यम से एक कोच और घोड़ों की सवारी" के लिए। यह एक महान वाक्यांश है जो मेरी इच्छा है कि मैंने और सुना।
निक हार्टले

2
अगर किसी को आपकी कक्षा को अपने अधीन करने की आवश्यकता है, तो शायद उसे आपके सुरक्षा उपायों तक पहुंच होनी चाहिए? और अगर आप किसी को कुछ लक्ष्य प्राप्त करने के लिए अपने सुरक्षा उपायों को बदलना नहीं चाहते हैं, तो शायद कोड साझा न करें? यह रूबी में इस तरह काम करता है - निजी सिफारिश की कम या ज्यादा है।
एडम लीबुसा

3
@ AdamLibuša "कोड साझा न करें"? जैसे ही आप किसी भी DLL को प्रकाशित करते हैं, आप कोड साझा कर रहे हैं - सभी संरचनाएं और विधियाँ और सब कुछ पूरी दुनिया के लिए हैं, विशेष रूप से उन भाषाओं के साथ जो डिफ़ॉल्ट रूप से प्रतिबिंब का समर्थन करते हैं। हर कोई जो कुछ भी कर सकता है, वह "आपके कोड" के साथ चाहता है - privateयह कहने का एक तरीका है कि "ये स्पर्श न करें", और इसे संकलक अनुबंध के भीतर लागू किया गया है। .NET जैसी प्रणालियों में, इसके महत्वपूर्ण सुरक्षा निहितार्थ भी हैं - आप केवल दूसरों के निजीकरण को छू सकते हैं जब आपको पूरा भरोसा है (मूल रूप से व्यवस्थापक / रूट एक्सेस के बराबर)।
लुअन

2
@ AdamLibuša मुझे लगता है कि आपकी उलझन मुख्य रूप से अलग-अलग ओओपी दृष्टिकोणों से अलग-अलग भाषाओं में उपजी है। OOP की जड़ (जैसा कि मूल रूप से परिभाषित किया गया है) मैसेजिंग है - इसका मतलब है कि आपके द्वारा दिए गए संदेशों को छोड़कर, सब कुछ निजी है। अधिकांश ओओपीश भाषाओं में, इसे "अपने डेटा को निजी रखें" के रूप में उजागर किया गया है - सार्वजनिक इंटरफ़ेस को यथासंभव छोटा बनाने का एक तरीका। एक ही तरीका है कि उपयोगकर्ता (यह एक उपवर्ग या अन्य वर्ग हो) को आपकी कक्षा में हेरफेर करने के लिए आपके द्वारा परिभाषित सार्वजनिक इंटरफ़ेस के माध्यम से है - आप अपनी कार को चलाने के लिए आमतौर पर स्टीयरिंग व्हील और पैडल का उपयोग कैसे करते हैं :)
लुअन

3
@Luaan +1 जब दूसरों के निजीकरण को छूने के लिए ठीक है!
निगेल टच

12

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

  1. तरीके उनके साथ पूर्व और बाद की स्थितियों (अनुबंध) से जुड़े हैं।
  2. वस्तुओं ने उनके साथ आक्रमणकारियों को जोड़ा है।

एक वस्तु के बारे में मॉड्यूलर तर्क इस प्रकार है (कम से कम पहले एक सन्निकटन के लिए)

  1. सिद्ध करो कि वस्तु का निर्माता आवेग स्थापित करता है
  2. प्रत्येक गैर-निजी विधि के लिए, ऑब्जेक्ट अपरिवर्तनीय और विधि पूर्ववर्ती प्रवेश पर पकड़ मानें, फिर यह साबित करें कि कोड का शरीर का अर्थ है कि विधि से बाहर निकलने पर पोस्टकॉन्डिशन और अपरिवर्तनीय पकड़

कल्पना करें कि हम object Aऊपर दिए गए दृष्टिकोण का उपयोग करके सत्यापित करते हैं। और अब की पुष्टि करना चाहते method gकी object Bजो कॉल method fकी object A। मॉड्यूलर तर्क हमें method gके कार्यान्वयन पर पुनर्विचार करने के लिए बिना कारण के बारे में अनुमति देता है method f। बशर्ते हम कॉल साइट पर object Aइनवॉयरमेंट ऑफ प्रिपेंडेंट ऑफ़ एंड प्रिपेंडिशन की स्थापना कर सकते हैं, हम मेथड कॉल के व्यवहार के सारांश के रूप में पोस्ट की स्थिति ले सकते हैं । इसके अलावा हम यह भी जानेंगे कि कॉल के वापस आने के बाद भी स्टिल के अपरिवर्तनीय है ।method fmethod g,method fA

तर्क की यह प्रतिरूपता हमें बड़े कार्यक्रमों के बारे में औपचारिक रूप से सोचने की अनुमति देती है। हम अलग-अलग तरीकों में से प्रत्येक के बारे में तर्क कर सकते हैं और फिर कार्यक्रम के बड़े हिस्सों के बारे में तर्क करने के लिए इस तर्क के परिणामों की रचना करते हैं।

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

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

संरक्षित खेत

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

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

हालांकि मैं औपचारिक तर्क के बारे में बात कर रहा हूं, लेकिन अक्सर यह सोचा जाता है कि जब प्रोग्रामर अपने कोड की शुद्धता के बारे में अनौपचारिक कारण बताते हैं तो वे भी कभी-कभी इसी तरह के तर्कों पर भरोसा करते हैं।


8

privateएक वर्ग में चर एक protectedही कारण से बेहतर हैं कि breakएक switchब्लॉक के अंदर एक goto labelबयान एक बयान से बेहतर है ; जो यह है कि मानव प्रोग्रामर त्रुटि-प्रवण हैं।

protectedवैरिएबल खुद को गैर-इरादतन दुरुपयोग (प्रोग्रामर गलतियों) के लिए gotoउधार देता है , जैसे कि बयान स्वयं स्पेगेटी कोड के निर्माण के लिए उधार देता है।

क्या protectedक्लास वेरिएबल्स का उपयोग करके वर्किंग बग-फ्री कोड लिखना संभव है ? हां बिल्कुल! जिस तरह से काम कर रहे बग-मुक्त कोड का उपयोग करना लिखना संभव है goto; लेकिन जैसा कि क्लिच "सिर्फ इसलिए कि आप कर सकते हैं, इसका मतलब यह नहीं है कि आपको चाहिए!"

कक्षाएं, और वास्तव में OO प्रतिमान, असहाय त्रुटि-ग्रस्त मानव प्रोग्रामर से गलती करने वाले के खिलाफ गार्ड के लिए मौजूद हैं। मानवीय गलतियों के खिलाफ रक्षा केवल कक्षा में निर्मित रक्षात्मक उपायों के रूप में अच्छी है। अपनी कक्षा के कार्यान्वयन protectedको एक किले की दीवारों में एक विशाल छेद को उड़ाने के बराबर है।

बेस कक्षाओं को व्युत्पन्न वर्गों का बिल्कुल ज्ञान नहीं है। जहां तक ​​आधार वर्ग का संबंध है, protectedवास्तव में आपको इससे अधिक सुरक्षा नहीं देता है public, क्योंकि एक व्युत्पन्न वर्ग को एक publicगेट्टर / सेटर बनाने से कुछ भी नहीं है जो एक पिछले दरवाजे की तरह व्यवहार करता है।

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

सबसे अच्छी बात यह है कि एक बेस क्लास कर सकता है, जितना संभव हो उतना इसके कार्यान्वयन को छिपा सकता है privateऔर व्युत्पन्न वर्गों से परिवर्तन को रोकने के लिए या कक्षा के बाहर कुछ भी करने के लिए पर्याप्त प्रतिबंध लगा सकता है।

अंत में, उच्च-स्तरीय भाषाएं मानवीय त्रुटियों को कम करने के लिए मौजूद हैं। अच्छी प्रोग्रामिंग प्रथाएं (जैसे कि SOLID सिद्धांत ) भी मानवीय त्रुटियों को कम करने के लिए मौजूद हैं।

सॉफ्टवेयर डेवलपर्स जो अच्छी प्रोग्रामिंग प्रथाओं को अनदेखा करते हैं, उनमें विफलता की संभावना अधिक होती है, और टूटे हुए अचूक समाधानों का उत्पादन करने की अधिक संभावना होती है। जो लोग अच्छी प्रथाओं का पालन करते हैं, उनमें असफलता की संभावना बहुत कम होती है, और काम करने योग्य बनाए रखने वाले समाधानों का उत्पादन करने की अधिक संभावना होती है।


डाउनवॉटर करने के लिए - इस उत्तर के बारे में क्या बदला / सुधार किया जा सकता है?
बेन कॉटरेल

मैंने वोट नहीं डाला, लेकिन ब्रेक / गोटो के साथ पहुँच स्तर की तुलना की?
imel96

@ imel96 नहीं है, कारण है कि वे परहेज कर रहे हैं, और द्वारा "सर्वश्रेष्ठ अभ्यास" (विशेष रूप से लिखने के लिए हतोत्साहित किया जाता है की तुलना नए कोड)। यानी एक सक्षम प्रोग्रामर publicकार्यान्वयन विवरणों से बचता है क्योंकि यह खुद को अचूक कोड के लिए उधार देता है। एक सक्षम प्रोग्रामर से बचना होगा gotoक्योंकि यह खुद को अचूक कोड के लिए उधार देता है। हालाँकि वास्तविक दुनिया ऐसी है कि कभी-कभी आप विरासत कोड की भयानक गड़बड़ी में खो जाते हैं, और उपयोग करने के अलावा कोई विकल्प नहीं होता है goto, और उसी कारण से आपके पास कभी-कभी सार्वजनिक / संरक्षित कार्यान्वयन विवरणों का उपयोग करने के अलावा कोई विकल्प नहीं होता है।
बेन कॉटरेल

गंभीरता परिमाण में भिन्न है, यह अतुलनीय है। मैं उस कोड के साथ रह सकता हूं जिसमें केवल publicगुण / इंटरफ़ेस हैं, लेकिन उस कोड के साथ नहीं जो केवल उपयोग करता है goto
imel96

2
@ imel96 क्या आपने कभी वास्तव में उस कोड में काम किया है जो उपयोग करता है gotoया यह सिर्फ इसलिए है क्योंकि आपने उस तरह के लेख पढ़े हैं? मैं समझता हूं कि goto बुराई क्यों है क्योंकि मैंने प्राचीन कोड में 2 साल बिताए हैं जो इसका उपयोग करता है; और मैंने उस कोड में काम करने में भी अधिक समय बिताया है, जहां "कक्षाओं" में उनके कार्यान्वयन के विवरण हर जगह लीक हो गए हैं publicऔर friendत्वरित / आसान / गंदे के रूप में उपयोग किए जाने वाले विनिर्देशक हैं। मैं इस तर्क को स्वीकार नहीं करता कि "कार्यान्वयन विवरणों को सार्वजनिक रूप से उजागर करना" गंभीरता के एक ही स्तर पर अंतर-मुड़ स्पेगेटी गड़बड़ का कारण नहीं बन सकता gotoक्योंकि यह बिल्कुल हो सकता है।
बेन कॉटरेल

4

इनहेरिटेबल कक्षाओं में दो अनुबंध होते हैं - एक वस्तु संदर्भ के धारकों के साथ, और व्युत्पन्न वर्गों के साथ। सार्वजनिक सदस्यों को संदर्भ धारकों के साथ अनुबंध द्वारा बाध्य किया जाता है, और संरक्षित सदस्य व्युत्पन्न वर्गों के साथ अनुबंध से बाध्य होते हैं।

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

एक उदाहरण के रूप List<T>में , .NET में बैकिंग स्टोर को निजी बनाता है; यदि इसे संरक्षित किया गया था, तो व्युत्पन्न प्रकार कुछ उपयोगी चीजें कर सकते हैं जो अन्यथा संभव नहीं हैं, लेकिन भविष्य के संस्करणों में List<T>हमेशा के लिए लाखों वस्तुओं को रखने वाली सूचियों के लिए भी अपने क्लॉन्की मोनोलिथिक बैकिंग स्टोर का उपयोग करना होगा। बैकिंग स्टोर को निजी बनाने से भविष्य के संस्करणों List<T>को व्युत्पन्न वर्गों को तोड़ने के बिना अधिक कुशल बैकिंग स्टोर का उपयोग करने की अनुमति मिलेगी ।


4

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

यदि उस धारणा को खारिज कर दिया जाता है तो विचार करने के लिए केवल दो मामले हैं।

  1. मूल वर्ग के लेखक के पास इस बात के लिए बहुत स्पष्ट विचार थे कि इसे क्यों बढ़ाया जा सकता है (जैसे कि यह एक बेसफू है और सड़क के नीचे कई ठोस फू कार्यान्वयन होंगे)।

इस मामले में, लेखक जानता है कि कोई व्यक्ति वर्ग का विस्तार करेगा और क्यों और इसलिए यह जान लेगा कि क्या संरक्षित किया जाए और क्या बनाया जाए। वे उपवर्ग बनाने वाले उपयोगकर्ता के लिए इंटरफ़ेस का संचार करने के लिए निजी / संरक्षित भेद का उपयोग कर रहे हैं।

  1. चाइल्ड क्लास का लेखक कुछ व्यवहारों को मूल कक्षा में हैक करने की कोशिश कर रहा है।

यह मामला दुर्लभ होना चाहिए (आप तर्क कर सकते हैं कि यह वैध नहीं है), और मूल कोड आधार में मूल वर्ग को संशोधित करने के लिए पसंद नहीं किया जाता है। यह खराब डिज़ाइन का लक्षण भी हो सकता है। उन मामलों में मैं व्यवहार में हैकिंग करने वाले व्यक्ति को सिर्फ दोस्तों (C / C ++) और setAccessible(true)(Java) जैसे अन्य हैक्स का उपयोग करना पसंद करूंगा ।

मुझे लगता है कि उस धारणा को खारिज करना सुरक्षित है।

यह आमतौर पर वंशानुक्रम पर रचना के विचार पर वापस आता है । संहिता पुन: उपयोग को कम करने के लिए विरासत को अक्सर एक आदर्श तरीके के रूप में पढ़ाया जाता है, हालांकि इसे कोड पुन: उपयोग के लिए शायद ही कभी पहली पसंद होना चाहिए। मेरे पास एक सरल नॉक-डाउन तर्क नहीं है और यह समझने में काफी कठिन और विवादास्पद हो सकता है। हालांकि, डोमेन मॉडलिंग के साथ अपने अनुभव में मैंने पाया है कि मैं शायद ही कभी विरासत का उपयोग करता हूं, जो मेरी कक्षा और क्यों विरासत में मिली होगी, इसकी स्पष्ट समझ के बिना।


2

सभी तीन पहुंच स्तरों का उनके उपयोग का मामला है, ओओपी उनमें से किसी की कमी होगी। आमतौर पर आप करते हैं

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

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


1

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

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


1

यहाँ बहुत सारे अच्छे जवाब हैं, लेकिन मैं अपने दो सेंट में वैसे भी फेंक दूँगा। :-)

निजी इसी कारण से अच्छा है कि वैश्विक डेटा खराब है।

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

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


1

मुझे लगता है कि कुछ असहमतिपूर्ण राय का उल्लेख करना उचित है।

सिद्धांत रूप में, अन्य उत्तरों में उल्लिखित सभी कारणों के लिए नियंत्रित स्तर का होना अच्छा है।

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

यह मुझे भी परेशान करता है, जिसका अर्थ है कि उनकी कक्षाएं संशोधन के लिए बंद नहीं हैं।

यह आंतरिक कोड के साथ था जहां आप हमेशा इसे बदल सकते हैं यदि आपको भी ज़रूरत है। तीसरी पार्टी कोड के साथ स्थिति बदतर है जब कोड बदलना इतना आसान नहीं है।

तो कितने प्रोग्रामर सोचते हैं कि यह एक परेशानी है? वैसे, प्रोग्रामिंग भाषा का उपयोग कितने लोग कर रहे हैं जिनके पास निजी नहीं है? बेशक, लोग केवल उन भाषाओं का उपयोग नहीं कर रहे हैं क्योंकि उनके पास निजी विनिर्देशक नहीं हैं, लेकिन यह भाषाओं को सरल बनाने में मदद करता है और सादगी महत्वपूर्ण है।

Imo यह गतिशील / स्थिर टाइपिंग के समान है। सिद्धांत रूप में, स्थैतिक टाइपिंग बहुत अच्छी है। व्यवहार में, यह केवल त्रुटियों के 2% की तरह से बचाता है गतिशील टाइपिंग की अव्यवाहारिक प्रभावशीलता ... । निजी का उपयोग करना शायद इससे कम त्रुटि को रोकता है।

मुझे लगता है कि SOLID सिद्धांत अच्छे हैं, मैं चाहता हूं कि लोग उनके बारे में अधिक परवाह करें, जितना वे सार्वजनिक, संरक्षित और निजी के साथ एक वर्ग बनाने के बारे में परवाह करते हैं।


1
यदि आपको इसका उपयोग करते समय 3rd पार्टी कोड बदलने की आवश्यकता है, या तो इसे अच्छी तरह से डिज़ाइन नहीं किया गया है, या तो आप इसे अच्छी तरह से पुन: उपयोग नहीं कर रहे हैं। आप हमेशा एक गैर-अमूर्त वर्ग को उसका एनकैप्सुलेट करके पुन: उपयोग कर सकते हैं, लेकिन व्यवहार में आपको शायद ही कभी इसे उप-वर्ग करने की आवश्यकता हो।
छोटी संटी

0

मैं एक और व्यावहारिक उदाहरण जोड़ना चाहूंगा कि क्यों protectedपर्याप्त नहीं है। मेरे विश्वविद्यालय में पहले वर्षों में एक परियोजना शुरू की जाती है जहाँ उन्हें एक बोर्ड गेम का डेस्कटॉप संस्करण विकसित करना होता है (जो बाद में एआई के लिए विकसित होता है और यह एक नेटवर्क पर अन्य खिलाड़ियों से जुड़ा होता है)। कुछ आंशिक कोड उन्हें प्रदान करने के लिए प्रदान किए जाते हैं ताकि उन्हें परीक्षण ढांचे सहित शुरू किया जा सके। मुख्य खेल वर्ग के कुछ गुणों को उजागर किया जाता है protectedताकि इस वर्ग का विस्तार करने वाले परीक्षण वर्गों तक उनकी पहुंच हो। लेकिन ये क्षेत्र संवेदनशील जानकारी नहीं हैं।

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

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


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

@sam कोड आम तौर पर इस धारणा के साथ लिखा जाना चाहिए कि जो कोई भी इसे संशोधित करता है उसे अंदर के पूरे कोडबेस को जानने की आवश्यकता नहीं होगी। यहां तक ​​कि कई बार मूल लेखक भी हो सकता है (समय गुजरना, नींद की कमी ...)। धोखा दे सकते हैं छात्रों को बाहर मांस के लिए कंकाल कोड दिया जा रहा है, और बदलते तर्क वे स्पर्श नहीं करना चाहिए।
फिल लेलो

0

निजी तरीके / चर आमतौर पर एक उपवर्ग से छिपे होंगे। यह एक अच्छी बात हो सकती है।

एक निजी विधि मापदंडों के बारे में धारणा बना सकती है और कॉल करने के लिए पवित्रता की जाँच कर सकती है।

एक संरक्षित पद्धति में इनपुट की जांच के लिए पवित्रता होनी चाहिए


-1

"निजी" का अर्थ है: केवल कक्षा को छोड़कर किसी के द्वारा परिवर्तित या एक्सेस किए जाने का इरादा नहीं है। उपवर्गों द्वारा परिवर्तित या एक्सेस किए जाने का इरादा नहीं है। उपवर्गों? क्या उपवर्ग? आप इस उपवर्ग के लिए नहीं कर रहे हैं!

"संरक्षित" का अर्थ है: केवल वर्गों या उपवर्गों द्वारा परिवर्तित या एक्सेस किए जाने का इरादा है। संभावना है कि आप उपवर्ग के लिए कटौती कर रहे हैं, अन्यथा "संरक्षित" और "निजी" क्यों नहीं?

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


-1

जब मैं एक वर्ग को उपवर्ग में रखता हूं तो पहली चीजों में से एक संरक्षित करने के लिए निजी तरीकों का एक गुच्छा बदलना है

privateबनाम protected तरीकों के बारे में कुछ तर्क :

privateतरीके कोड के पुन: उपयोग को रोकते हैं। एक उपवर्ग निजी पद्धति में कोड का उपयोग नहीं कर सकता है और इसे फिर से लागू करना पड़ सकता है - या विधि (ओं) को फिर से लागू कर सकता है जो मूल रूप से निजी विधि और सी पर निर्भर करते हैं।

दूसरी ओर, किसी भी विधि को "बाहरी दुनिया" के लिए कक्षा द्वारा प्रदान की गई एपीआई के रूप में नहीं private देखा जा सकता है, इस अर्थ में कि तीसरे पक्ष के उपवर्गों को "बाहरी दुनिया" भी माना जाता है, जैसा कि उनके जवाब में किसी और ने सुझाया है। पहले से।

क्या यह गलत बात है? - मुझे ऐसा नहीं लगता।

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

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

बहुत सारे (फ्रेमवर्क) कोड मैं देख रहा हूं कि एक असंगत उपयोग को अपनाया जाता है private: protectedगैर-अंतिम तरीके जो निजी तौर पर एक निजी पद्धति को सौंपने से ज्यादा कुछ नहीं करते हैं। protected, गैर-अंतिम विधियां, जिनका अनुबंध केवल निजी क्षेत्रों तक सीधी पहुंच के माध्यम से भी पूरा किया जा सकता है।

इन विधियों को तार्किक रूप से अधिग्रहित / बढ़ाया नहीं जा सकता है, हालांकि तकनीकी रूप से ऐसा करने के लिए कुछ भी नहीं है (संकलक) स्पष्ट।

विस्तार और विरासत चाहते हैं? अपने तरीके मत बनाओ private

अपनी कक्षा के कुछ व्यवहार को बदलना नहीं चाहते हैं? अपने तरीके बनाओ final

वास्तव में आपकी पद्धति एक निश्चित, अच्छी तरह से परिभाषित संदर्भ के बाहर नहीं हो सकती है? अपनी विधि बनाएं privateऔर / या इस बारे में सोचें कि आप किसी अन्य protectedआवरण विधि के माध्यम से पुन: उपयोग के लिए आवश्यक अच्छी तरह से परिभाषित संदर्भ कैसे उपलब्ध कर सकते हैं ।

इसलिए मैं privateसंयम बरतने की वकालत करता हूं । और privateसाथ भ्रमित करने के लिए नहीं final। - यदि किसी विधि का कार्यान्वयन कक्षा के सामान्य अनुबंध के लिए महत्वपूर्ण है और इस प्रकार इसे प्रतिस्थापित / ओवरराइड नहीं किया जाना चाहिए, तो करें final!

खेतों के लिए, privateवास्तव में बुरा नहीं है। जब तक क्षेत्र (ओं) को उचित तरीकों के माध्यम से यथोचित "उपयोग" किया जा सकता है (वह है या नहीं !)।getXX()setXX()


2
-1 यह privateबनाम protectedमूल प्रश्न को संबोधित नहीं करता है , गलत सलाह देता है (" privateसंयम से उपयोग करें "?) और ओओ डिजाइन पर सामान्य सहमति के खिलाफ जाता है। का उपयोग privateकरते हुए मैला कोड छिपाने के साथ कुछ नहीं करना है।
एंड्रेस एफ।

3
आप उल्लेख करते हैं कि एक वर्ग में एक एपीआई है, लेकिन ऐसा कनेक्शन नहीं लगता है कि एपीआई का उपयोगकर्ता उन विवरणों से बोझिल नहीं होना चाहता है जिन्हें उन्हें जानने की आवश्यकता नहीं है। एक वर्ग के उपयोगकर्ता के लिए आदर्श स्थिति इंटरफ़ेस के लिए होती है जिसमें केवल उनकी ज़रूरत के तरीके होते हैं, और कुछ नहीं। तरीकों को बनाने privateसे एपीआई को साफ रखने में मदद मिलती है।
बेन कॉटरेल

1
@ हन्नोइंदर मैं मानता हूं कि वहां बहुत सारी कक्षाएं हैं जो कठोरता से ग्रस्त हैं, हालांकि लचीलापन और कोड का पुन: उपयोग इनकैप्सुलेशन और दीर्घकालिक स्थिरता से बहुत कम महत्वपूर्ण है। अपने मामले पर विचार करें जहां सभी वर्गों के सदस्यों की रक्षा की गई है और व्युत्पन्न वर्ग किसी भी कार्यान्वयन विवरण के बारे में बता सकते हैं जो वे चाहते हैं; आप विश्वसनीय रूप से उन वर्गों का परीक्षण कैसे करते हैं, जो यह जानते हुए भी कि किसी भी हिस्से में अभी तक अलिखित कोड के कारण कुछ भी हो सकता है? इससे पहले कि कितने "हैक्स" कोड ले सकते हैं इससे पहले कि यह सभी मिट्टी की एक बड़ी गेंद में गिर जाए?
बेन कॉटरेल

2
ओह, आपने "सदस्य" कहा। मैं जो कह रहा हूं, वह केवल तरीकों का जिक्र है । सदस्य चर (क्षेत्र) एक अलग कहानी है, जहां गोपनीयता बहुत अधिक न्यायसंगत है।
जिमीबी

2
चर्चा में नामकरण सभी जगह है क्योंकि यह एक विशेष भाषा के लिए विशिष्ट नहीं है। C ++ में "सदस्य" डेटा, फ़ंक्शन, प्रकार या टेम्पलेट हो सकता है।
जडलुगोज़

-1

क्या आप एक महत्वपूर्ण उपयोग के मामले के बारे में जानते हैं, जहां संरक्षित के बजाय निजी एक अच्छा उपकरण है, या दो विकल्प "संरक्षित और सार्वजनिक" होगा जो बीओपी भाषाओं के लिए पर्याप्त है?

निजी : जब आपके पास कुछ ऐसा हो जो किसी उपवर्ग के लिए कॉल या ओवरराइड करने के लिए उपयोगी नहीं होगा।

संरक्षित : जब आपके पास कुछ ऐसा हो, जिसमें उप-विशिष्ट-विशिष्ट कार्यान्वयन / स्थिरांक हो।

एक उदाहरण:

public abstract Class MercedesBenz() extends Car {
  //Might be useful for subclasses to know about their customers
  protected Customer customer; 

  /* Each specific model has its own horn. 
     Therefore: protected, so that each subclass might implement it as they wish
  */
  protected abstract void honk();

  /* Taken from the car class. */
  @Override
  public void getTechSupport(){
     showMercedesBenzHQContactDetails(customer);
     automaticallyNotifyLocalDealer(customer);
  }

  /* 
     This isn't specific for any subclass.
     It is also not useful to call this from inside a subclass,
     because local dealers only want to be notified when a 
     customer wants tech support. 
   */
  private void automaticallyNotifyLocalDealer(){
    ...
  }
}

2
जब आपके पास ऐसा कुछ है जो किसी भी उपवर्ग के लिए कॉल या ओवरराइड करने के लिए उपयोगी नहीं होगा - और यह कुछ ऐसा है जो आप, मेरी राय में, पहले से कभी नहीं जानते हैं।
एडम लिबुसा

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

-2

इस मामले को समझना मेरे लिए कठिन था, इसलिए मैं अपने अनुभव का एक अंश साझा करना चाहूंगा:

  • संरक्षित क्षेत्र क्या है ? यह एक क्षेत्र से अधिक कुछ भी नहीं है , जिसे एक वर्ग के बाहर नहीं पहुँचा जा सकता है, अर्थात इस तरह से यौवन$classInstance->field :। और चाल है कि यह "यह है"। आपकी कक्षा के बच्चों की पूरी पहुँच होगी, क्योंकि यह उनका सही आंतरिक हिस्सा है।
  • निजी क्षेत्र क्या है ? यह आपके अपने वर्ग के लिए एक " सच्चा निजी " है और इस वर्ग का आपका अपना कार्यान्वयन है। "बच्चों की पहुंच से बाहर रखें", जैसे एक दवा की बोतल पर। आपको इस बात की गारंटी होगी कि यह आपके वर्ग के व्युत्पन्न, आपके तरीकों से अप्राप्य है - जब कहा जाता है - तो आपके द्वारा घोषित किए गए सटीक परिणाम होंगे

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


क्षमा करें दोस्तों! बस उन्हें गड़बड़ कर दिया - मेरे जवाब को अद्यतन करना =) धन्यवाद! मैं जल्दी में था और गलत तरीके से =)
एलेक्सी वेसिन

2
मुझे लगता है कि ओपी को दो सुरक्षा स्तरों के बीच अंतर के बारे में पता है, लेकिन इस बात में दिलचस्पी है कि एक का उपयोग दूसरे के ऊपर क्यों किया जाना चाहिए।
सैम

@ सॅम कृपया मेरे उत्तर का गहन पठन करें। वे पूरी तरह से विभिन्न प्रकार के क्षेत्र हैं! केवल बात यह है कि वे आम में है कि वे दोनों सार्वजनिक रूप से संदर्भित नहीं किया जा सकता है
एलेक्सी Vesnin

2
मुझे यकीन नहीं है कि आप किस बारे में बात कर रहे हैं। मुझे निजी और संरक्षित के बीच अंतर के बारे में पता है। शायद आप गलत समझ गए कि सुरक्षा के स्तर से मेरा क्या मतलब है? मैं 'एक्सेस लेवल' की बात कर रहा हूँ। मैं यह बताने की कोशिश कर रहा था कि आपका उत्तर खराब नहीं है, यह सीधे सवाल का जवाब नहीं देता है। ओपी को यह पता चलता है कि संरक्षित / निजी / सार्वजनिक दोनों का क्या मतलब है, लेकिन यह निश्चित नहीं है कि वे किन परिस्थितियों में एक दूसरे को चुनना चाहेंगे। यह तरीका हो सकता है कि आपको वोट दिया जाए (मेरे द्वारा नहीं)।
सैम

@ मुझे लगता है कि मुझे आपकी बात मिल गई है - मेरे वास्तविक अभ्यास / अनुभव से एक व्यावहारिक मामला जोड़ा गया है। क्या आपकी बात याद आ रही है?
एलेक्सी वेसनिन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.