कक्षाओं को "खुला" होने के लिए डिज़ाइन क्यों नहीं किया जाना चाहिए?


44

विभिन्न स्टैक ओवरफ्लो प्रश्नों और दूसरों के कोड को पढ़ते समय, कक्षाओं को कैसे डिज़ाइन किया जाए, इस बारे में आम सहमति। इसका मतलब यह है कि जावा और सी # में डिफ़ॉल्ट रूप से सब कुछ निजी है, फ़ील्ड अंतिम हैं, कुछ तरीके अंतिम हैं, और कभी-कभी कक्षाएं भी अंतिम हैं

इसके पीछे विचार कार्यान्वयन विवरणों को छिपाना है, जो एक बहुत अच्छा कारण है। हालांकि protectedअधिकांश ओओपी भाषाओं और बहुरूपता के अस्तित्व के साथ , यह काम नहीं करता है।

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

  • कक्षा का विस्तार न करें, बस उस समस्या के आसपास काम करें जिससे कोड अधिक जटिल हो
  • पूरी कक्षा को कॉपी और पेस्ट करें, कोड पुन: प्रयोज्य की हत्या
  • परियोजना को कांटा

वे अच्छे विकल्प नहीं हैं। protectedइसका समर्थन करने वाली भाषाओं में लिखी जाने वाली परियोजनाओं में उपयोग क्यों नहीं किया जाता है? कुछ परियोजनाएं स्पष्ट रूप से अपनी कक्षाओं से विरासत में लेने पर प्रतिबंध क्यों लगाती हैं?


1
मैं सहमत हूं, मुझे जावा स्विंग घटकों के साथ यह समस्या थी, यह वास्तव में बुरा है।
जोनास


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

2
"सबसे अधिक ओओपी भाषाएँ?" मुझे और भी बहुत कुछ पता है जहाँ कक्षाएं बंद नहीं की जा सकतीं। आपने चौथे विकल्प को छोड़ दिया: भाषा बदलें।
केविन क्लाइन

@ जोनास स्विंग की प्रमुख समस्याओं में से एक यह है कि यह बहुत अधिक कार्यान्वयन का रास्ता उजागर करता है। जो वास्तव में विकास को मारता है।
टॉम हॉल्टिन -

जवाबों:


55

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

तो यह इतना नहीं है कि कक्षाएं खुली नहीं होनी चाहिए, लेकिन कभी-कभी यह उन्हें खोलने के प्रयास के लायक नहीं है।

बेशक, यह भी संभव है कि पुस्तकालय लेखक सिर्फ आलसी हो रहे थे। निर्भर करता है कि आप किस लाइब्रेरी के बारे में बात कर रहे हैं। :-)


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


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

5
@ एलक्यूक्यू: यह एक बहुत बड़ी धारणा है।
रॉबर्ट हार्वे

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

24

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

अंतर्निहित विचार 'ढीला युग्मन' (जिसे 'संकीर्ण इंटरफेस' भी कहा जाता है); इसकी कीमत जटिलता को बनाए रखने में निहित है। घटकों को बातचीत करने के तरीकों की संख्या को कम करके, उनके बीच क्रॉस-निर्भरता की मात्रा भी कम हो जाती है; जब रखरखाव और प्रबंधन को बदलने की बात आती है तो क्रॉस-निर्भरता सबसे खराब प्रकार की जटिलता है।

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


यह कुछ समझ में आता है। अभी भी समस्या है जब आपको कुछ समान की आवश्यकता होती है, लेकिन कार्यान्वयन में 1 या 2 चीजें बदल जाती हैं (वर्ग के आंतरिक कामकाज)। मैं यह समझने के लिए भी संघर्ष कर रहा हूं कि यदि आपकी कक्षा ओवरराइड कर रही है, तो क्या आप पहले से ही इसके कार्यान्वयन पर भारी नहीं हैं?
20

5
ढीली युग्मन के लाभों के लिए +1। @ TheLQ, यह इंटरफ़ेस है जो आपको भारी होना चाहिए, कार्यान्वयन पर नहीं।
कार्ल बेलेफेल्ट्ट

19

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

"अंतिम" सम्मान के बारे में। "सील" कक्षाएं, एक विशिष्ट मामला अपरिवर्तनीय कक्षाएं हैं। ढांचे के कई हिस्से अपरिवर्तनीय होने वाले तारों पर निर्भर करते हैं। यदि स्ट्रिंग वर्ग अंतिम नहीं था, तो एक स्थिर स्ट्रिंग उपवर्ग बनाने के लिए यह आसान (यहां तक ​​कि आकर्षक) होगा कि अपरिवर्तनीय स्ट्रिंग वर्ग के बजाय कई अन्य वर्गों में सभी प्रकार के कीड़े पैदा हो जाएं।


4
यही असली जवाब है। अन्य उत्तर महत्वपूर्ण चीजों पर स्पर्श करते हैं लेकिन वास्तविक प्रासंगिक बिट यह है: वह सब कुछ जो final/ और नहीं है या privateजगह में बंद है और कभी भी बदला नहीं जा सकता है
कोनराड रुडोल्फ

1
@Konrad: जब तक डेवलपर्स सब कुछ सुधारने और गैर-पीछे-संगत होने का निर्णय लेते हैं।
JAB

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

14

OO में मौजूदा कोड में कार्यक्षमता जोड़ने के दो तरीके हैं।

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

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

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


5
रचना बनाम विरासत के साथ महान बिंदु।
Zsolt Török

+1, लेकिन मुझे यह पसंद नहीं है कि विरासत के लिए "एक आकार" उदाहरण है। एक आयत और एक वृत्त दो बहुत अलग चीजें हो सकती हैं। मुझे उपयोग करना अधिक पसंद है, एक वर्ग एक आयत है जो विवश है। आयतों का उपयोग आकृतियों की तरह किया जा सकता है।
टाइलेरमैक

@tylermac: वास्तव में। स्क्वायर / आयत का मामला वास्तव में एलएसपी के प्रतिपक्षों में से एक है। शायद, मुझे अधिक प्रभावी उदाहरण के बारे में सोचना चाहिए।
knulp

3
यदि आप संशोधन की अनुमति देते हैं तो स्क्वायर / आयत केवल एक प्रतिरूप है।
Starblue

11

अधिकांश उत्तरों में यह अधिकार होता है: जब ऑब्जेक्ट डिज़ाइन नहीं किया जाता है या विस्तारित होने का इरादा होता है, तो कक्षाएं सील की जानी चाहिए (अंतिम, ध्यान देने योग्य, आदि)।

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

उदाहरण के लिए, एक वर्ग "कंसोलवॉटर" पाठ प्राप्त कर सकता है और इसे कंसोल में आउटपुट कर सकता है। यह यह अच्छी तरह से करता है। हालाँकि, एक निश्चित मामले में आपको ALSO को फ़ाइल में लिखे समान आउटपुट की आवश्यकता होती है। ConsoleWriter का कोड खोलना, इसके बाहरी इंटरफ़ेस को मुख्य कार्यों के लिए एक पैरामीटर "WriteToFile" में जोड़ना, और कंसोल-राइटिंग कोड के आगे अतिरिक्त फ़ाइल-राइटिंग कोड को रखना आमतौर पर एक बुरी बात मानी जाएगी।

इसके बजाय, आप दो चीजों में से एक कर सकते हैं: आप कंसोल कंसोल से व्युत्पन्न कर सकते हैं, कंसोल कंसोल बनाने के लिए, और आधार कार्यान्वयन को कॉल करने के लिए राइट () विधि का विस्तार करें और फिर एक फाइल पर भी लिखें। या, आप ConsoleWriter से एक इंटरफ़ेस IWriter निकाल सकते हैं, और दो नए वर्ग बनाने के लिए उस इंटरफ़ेस को फिर से लागू कर सकते हैं; एक FileWriter, और एक "MultiWriter" जिसे अन्य IWriters दिए जा सकते हैं और सभी दिए गए लेखकों को इसके तरीकों के लिए किए गए किसी भी कॉल का "प्रसारण" करेंगे। आप जो चुनते हैं वह इस बात पर निर्भर करता है कि आपको क्या चाहिए; सरल व्युत्पत्ति, ठीक है, सरल है, लेकिन अगर आपके पास नेटवर्क क्लाइंट, तीन फाइलें, दो नामित पाइप और कंसोल पर संदेश भेजने के लिए अंततः मंद होने की दूरदर्शिता है, तो आगे बढ़ें और इंटरफ़ेस निकालने के लिए परेशानी उठाएं। "वाई-अनुकूलक"; यह

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


अच्छी बात। वंशानुक्रम अच्छा या बुरा हो सकता है, इसलिए यह कहना गलत है कि हर वर्ग को सील किया जाना चाहिए। यह वास्तव में हाथ में समस्या पर निर्भर करता है।
घुंघरू

2

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

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


7
BTW, OO और प्रक्रियात्मक सबसे सशक्त रूप से पारस्परिक रूप से अनन्य नहीं हैं। आप प्रक्रियाओं के बिना OO नहीं कर सकते। इसके अलावा, रचना विस्तार के रूप में सिर्फ एक ओओ अवधारणा है।
माइकल के

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

1
यह हल किया जा सकता है, अगर जावा में प्रथम श्रेणी के कार्य थे। भावहीन।
माइकल के

नए छात्रों को जावा या डॉटनेट भाषाएँ सिखाना कठिन है। मैं आमतौर पर प्रक्रियात्मक पास्कल या "प्लेन सी" के साथ प्रक्रियात्मक सिखाता हूं, और बाद में, ऑब्जेक्ट पास्कल या "सी ++" के साथ ओओ पर स्विच करता हूं। और, जावा को बाद के लिए छोड़ दें। प्रक्रियात्मक कार्यक्रमों के साथ शिक्षण प्रोग्रामिंग एक एकल (सिंगलटन) ऑब्जेक्ट की तरह दिखता है जो अच्छी तरह से काम करता है।
umlcat

@ मिचेल के: ओओपी में एक प्रथम श्रेणी का कार्य केवल एक विधि के साथ एक वस्तु है।
जियोर्जियो

2

क्योंकि वे किसी भी बेहतर पता नहीं है।

मूल लेखक संभवतः SOLID सिद्धांतों की गलतफहमी से चिपके हुए हैं जो एक उलझन और जटिल सी ++ दुनिया में उत्पन्न हुए हैं।

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

कक्षाओं को सील करना और किसी भी सदस्य को निजी चिह्नित करना इस सिद्धांत का स्पष्ट रूप से उल्लंघन करता है कि सरल चीजें सरल होनी चाहिए और कठिन चीजें संभव होनी चाहिए। अचानक चीजें जो सरल होनी चाहिए, नहीं हैं।

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

  1. अहंकार - वे वास्तव में विश्वास करते थे कि वे विस्तार के लिए खुले थे और संशोधन के लिए बंद थे
  2. शालीनता - उन्हें पता था कि अन्य उपयोग के मामले हो सकते हैं लेकिन उन उपयोग मामलों के लिए नहीं लिखने का फैसला किया

मुझे लगता है कि कॉरपोरेट ढांचे में, # 2 शायद मामला है। उन सी ++, जावा और .NET फ्रेमवर्क को "किया" जाना है और उन्हें कुछ दिशानिर्देशों का पालन करना होगा। उन दिशानिर्देशों का आमतौर पर मतलब होता है सील किए गए प्रकार जब तक कि प्रकार स्पष्ट रूप से एक प्रकार के पदानुक्रम और निजी सदस्यों के हिस्से के रूप में डिज़ाइन नहीं किया गया था, जो कई चीजों के लिए उपयोगी हो सकते हैं जो दूसरों के उपयोग के लिए उपयोगी हो सकते हैं .. लेकिन चूंकि वे सीधे उस वर्ग से संबंधित नहीं हैं, इसलिए वे उजागर नहीं होते हैं । एक नया प्रकार निकालना समर्थन, दस्तावेज़ आदि के लिए बहुत महंगा होगा ...

एक्सेस मॉडिफायर्स के पीछे पूरा विचार यह है कि प्रोग्रामर्स को खुद से सुरक्षित किया जाए। "सी प्रोग्रामिंग खराब है क्योंकि यह आपको पैर में खुद को शूट करने देता है।" यह एक दर्शन नहीं है कि मैं एक प्रोग्रामर के रूप में सहमत हूं।

मैं अजगर के नाम के दृष्टिकोण को बहुत पसंद करता हूं। आप आसानी से (प्रतिबिंब की तुलना में बहुत आसान हो सकते हैं) यदि आवश्यक हो तो निजीकरण को प्रतिस्थापित करें। इस पर एक बढ़िया राइटअप यहाँ उपलब्ध है: http://bytebaker.com/2009/03/31/python-properties-vs-java-access-modifiers/

रूबी का निजी संशोधक वास्तव में C # में संरक्षित है और C # संशोधक के रूप में निजी नहीं है। संरक्षित थोड़ा अलग है। यहाँ बहुत व्याख्या है: http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/

याद रखें, आपकी स्थिर भाषा को उस भाषा के अतीत में कोड रिट की प्राचीन शैली के अनुरूप नहीं होना चाहिए।


5
"एनकैप्सुलेशन ने कभी भी पूर्ण सफलता का प्रदर्शन नहीं किया है"। मैंने सोचा होगा कि हर कोई इस बात से सहमत होगा कि एनकैप्सुलेशन की कमी के कारण बहुत परेशानी हुई है।
जोह

5
-1। फ़ूल दौड़ते हैं जहाँ फ़रिश्ते डरते हैं। निजी चर को बदलने की क्षमता का जश्न मनाना आपकी कोडिंग शैली में एक गंभीर दोष दर्शाता है।
रिवल

2
विवादित होने और शायद गलत होने के अलावा, यह पोस्ट काफी अहंकारी और अपमानजनक भी है। अच्छी तरह से किया।
कोनराड रुडोल्फ

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

1

संपादित करें: मेरा मानना ​​है कि कक्षाएं खुली होनी चाहिए। कुछ प्रतिबंधों के साथ, लेकिन विरासत के लिए बंद नहीं किया जाना चाहिए।

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

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

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

class MyBaseWrapper {
  protected FinalClass _FinalObject;

  public virtual DoSomething()
  {
    // these method cannot be overriden,
    // its from a "final" class
    // the wrapper method can  be open and virtual:
    FinalObject.DoSomething();
  }
} // class MyBaseWrapper


class MyBaseWrapper: MyBaseWrapper {

  public override DoSomething()
  {
    // the wrapper method allows "overriding",
    // a method from a "final" class:
    DoSomethingNewBefore();
    FinalObject.DoSomething();
    DoSomethingNewAfter();
  }
} // class MyBaseWrapper

स्कोप क्लैसिफायर विरासत को प्रतिबंधित किए बिना कुछ सुविधाओं को "सील" करने की अनुमति देते हैं।

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

PS मुझे C # में कीवर्ड के रूप में "फाइनल" पसंद नहीं है, मैं विरासत के रूपक के बाद जावा, या "बाँझ" जैसे "सील" का उपयोग करता हूं। इसके अलावा, "अंतिम" एक अस्पष्ट शब्द है जिसका उपयोग कई संदर्भों में किया जाता है।


-1: आपने कहा था कि आप खुले डिजाइन पसंद करते हैं, लेकिन यह सवाल का जवाब नहीं देता है, यही कारण है कि कक्षाओं को खुले रहने के लिए डिज़ाइन नहीं किया जाना चाहिए।
जोह

@ जोह सॉरी, मैंने खुद को अच्छी तरह से समझाया नहीं, मैंने विपरीत राय व्यक्त करने की कोशिश की, वहां सील नहीं होनी चाहिए। वर्णन के लिए धन्यवाद कि आप असहमत क्यों हैं।
umlcat
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.