आप कक्षा को कब और क्यों सील करेंगे?


87

C # और C ++ / CLI में कीवर्ड sealed(या NotInheritableVB में) का उपयोग किसी भी वंशानुक्रम के मौके से वर्ग की सुरक्षा के लिए किया जाता है (वर्ग गैर-अंतर्निहित होगा)। मुझे पता है कि ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग की एक विशेषता वंशानुक्रम है और मुझे लगता है कि sealedइस सुविधा के खिलाफ जाने का उपयोग , यह विरासत को रोकता है। क्या कोई उदाहरण है जो इसका लाभ दिखाता है sealedऔर इसका उपयोग कब करना महत्वपूर्ण है?

जवाबों:


96
  1. एक वर्ग जो सुरक्षा सुविधाओं को लागू करता है, ताकि मूल वस्तु "प्रतिरूपित" न हो सके।

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

आजकल बाजार में अधिकांश प्रदर्शन-बढ़ाने वाले टूल में, आपको एक चेकबॉक्स मिलेगा, जो आपके सभी वर्गों को सील कर देगा जो विरासत में नहीं मिले हैं।
यद्यपि सावधान रहें, क्योंकि यदि आप MEF के माध्यम से प्लगइन्स या असेंबली खोज की अनुमति देना चाहते हैं, तो आप समस्याओं में भाग लेंगे।


3
मेरा मतलब था कि पुन: उपयोग की जाने वाली पुस्तकालयों में सीलिंग कक्षाओं के साथ सावधान रहना, खासकर यदि वे तीसरे पक्ष द्वारा पुन: उपयोग किए जाने वाले हैं और फिर कोडबेस में पुन: एकीकृत (MEF के माध्यम से)। आपका कोडबेस किसी दिए गए वर्ग को विरासत में नहीं दे सकता है लेकिन तीसरे पक्ष को देगा।
लुई कोट्टमन

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

1
यह महंगा प्रदर्शन-वार हो जाता है अगर अनुपचारित छोड़ दिया जाता है, तो क्या यह भी कम औसत दर्जे का पागल परीक्षण है?
t3chb0t

4
सील चूसता है। यह कठिन परीक्षण करता है - मैं FakeItEasy के साथ कुछ ASP.NET वर्गों का मजाक बनाना चाहूंगा, लेकिन मैं नहीं कर सकता क्योंकि वे सील हैं।
युद्ध समान चिंपांज़ी

2
@RayLuo से अधिक सहमत नहीं हो सकते। मैंने इसे कई बार मारा कि लोगों ने अपनी कक्षाएं सील कर दीं जहां सुरक्षा और प्रदर्शन वास्तव में समस्या नहीं है। उनकी "सील" ने कक्षाओं को ओवरराइड करने की मेरी उचित आवश्यकता को रोक दिया, चीजों को और अधिक कठिन बना दिया। जैसे वॉरिएंट चिंपांज़ी ने कहा, परीक्षण में एक वर्ग का मज़ाक उड़ाना आम है।
ZZY

15

बबून के उत्कृष्ट उत्तर के लिए एक परिशिष्ट :

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

संबंधित नोट पर, केवल बिना वर्ग की कक्षाओं के लिए लागू: बनाई गई कोई भी विधि virtualएक विस्तार बिंदु है, या कम से कम ऐसा लगता है कि यह एक विस्तार बिंदु होना चाहिए। घोषणा के तरीकों के virtualसाथ-साथ एक सचेत निर्णय होना चाहिए। (C # में यह एक सचेत निर्णय है; जावा में यह नहीं है।)


संपादित करें : कुछ प्रासंगिक लिंक:

यह भी ध्यान दें कि कोटलिन डिफ़ॉल्ट रूप से कक्षाएं सील करता है; इसका openकीवर्ड जावा के finalया sealedC # के विपरीत है । (यह सुनिश्चित करने के लिए, कोई सार्वभौमिक समझौता नहीं है कि यह एक अच्छी बात है ।)


25
सीलिंग कक्षाएं लाभ की तुलना में अधिक सिरदर्द का कारण बनती हैं। मैंने लगातार ऐसी स्थितियां देखीं, जहां डेवलपर्स ने कक्षाएं सील कर दी हैं, जिससे मुझे घंटों की कठिनाई का सामना करना पड़ता है जो सरल होना चाहिए। सीलिंग क्लासेस बंद करें, आप उतने मजाकिया नहीं हैं जितना आप सोचते हैं कि आप हैं। सील कक्षाएं केवल यदि आप जरूरी हैं, और फिर भी, पुनर्विचार करें। बस मेरी राय, उस आदमी के रूप में जिसे अन्य लोगों की सीलबंद कक्षाओं से निपटना है जिन्हें मैं संपादित / अनसुना नहीं कर सकता।
गैंट लाबोर्दे

9
@GantMan की टिप्पणी को वास्तव में ओपी के प्रश्न के उत्तर में से एक माना जाना चाहिए, क्योंकि यह अनिवार्य रूप से "जब? मुश्किल है। क्यों? के रूप में एक उत्तर देता है। यही कारण है कि आप ऐसा नहीं करते हैं।" अनुदान आपको अपनी टिप्पणी को एक अलग उत्तर के रूप में फिर से पोस्ट करना चाहिए और फिर इसके लिए वोट एकत्र करना चाहिए। :-)
रायलू

1
क्या यह उत्तर इस प्रकार था: stackoverflow.com/a/7777674/3195477 ? इसके (केवल) से लिंक करने के लिए बेहतर है कि व्यक्ति का नाम
UUDdLrLrSs

2

एक वर्ग को चिह्नित करना Sealedमहत्वपूर्ण सुरक्षा वर्गों से छेड़छाड़ को रोकता है जो सुरक्षा से समझौता कर सकते हैं, या प्रदर्शन को प्रभावित कर सकते हैं।

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

उदाहरण के लिए, Systemनेमस्पेस C#कई वर्गों को प्रदान करता है जो सील कर दिए जाते हैं, जैसे कि String। यदि सील नहीं किया गया है, तो इसकी कार्यक्षमता को बढ़ाना संभव होगा, जो अवांछनीय हो सकता है, क्योंकि यह एक बुनियादी प्रकार है जो दी गई कार्यक्षमता है।

इसी तरह, structuresमें C#हमेशा परोक्ष सील कर रहे हैं। इसलिए एक संरचना / वर्ग को दूसरी संरचना से प्राप्त नहीं किया जा सकता है। इसका तर्क यह है कि structuresकेवल स्टैंड-अलोन, परमाणु, उपयोगकर्ता-परिभाषित डेटा प्रकारों को मॉडल करने के लिए उपयोग किया जाता है , जिसे हम संशोधित नहीं करना चाहते हैं।

कभी-कभी, जब आप कक्षा पदानुक्रम का निर्माण कर रहे होते हैं, तो आप अपने डोमेन मॉडल या व्यावसायिक नियमों के आधार पर विरासत श्रृंखला में एक निश्चित शाखा को बंद करना चाह सकते हैं।

उदाहरण के लिए, ए Managerऔर PartTimeEmployeeदोनों Employeeएस हैं, लेकिन आपके संगठन में अंशकालिक कर्मचारियों के बाद आपकी कोई भूमिका नहीं है। इस मामले में, आप PartTimeEmployeeआगे की शाखाओं को रोकने के लिए सील करना चाह सकते हैं । दूसरी ओर, यदि आपके पास प्रति घंटा या साप्ताहिक अंशकालिक कर्मचारी हैं, तो हो सकता है कि यह उनसे विरासत में मिले PartTimeEmployee


स्ट्रिंग वर्ग का विस्तार करना अवांछनीय कैसे होगा? स्ट्रिंग अभी भी ठीक उसी तरह काम करेगा जैसे यह वर्तमान में कैसे करता है, और आपके पास वांछित होने पर अतिरिक्त कार्यक्षमता के साथ एक व्युत्पन्न वर्ग हो सकता है, इसलिए आप किस मुद्दे पर बात कर रहे हैं?
केविन वेल्स

इसके अलावा आपके वंशानुक्रम पदानुक्रम को "कैपिंग" करने का क्या मतलब होगा? इसका मतलब यह होगा कि अगर आपको कभी उस पदानुक्रम का विस्तार करने की आवश्यकता है, तो आपको सबसे पहले मूल वर्ग को हटाना होगा, जो सिर्फ अक्षम है
केविन वेल्स

एरिक लिपर्ट और इस एसओ सवाल से इस उत्कृष्ट पोस्ट की जाँच करें ।
अक्षय खट

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

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

0

मुझे लगता है कि इस पोस्ट में कुछ अच्छा बिंदु है, विशिष्ट मामला तब था जब एक गैर-सील वर्ग को किसी भी यादृच्छिक इंटरफ़ेस में डालने की कोशिश की जा रही थी, संकलक त्रुटि नहीं फेंकता है; लेकिन जब सील का उपयोग किया जाता है संकलक त्रुटि है कि यह परिवर्तित नहीं कर सकता है। सील वर्ग अतिरिक्त कोड एक्सेस सुरक्षा लाता है।
https://www.codeproject.com/Articles/239939/Csharp-Tweaks-Why-to-use-the-sealed-keyword-on-cla


1
किसी समाधान के लिए लिंक का स्वागत है, लेकिन कृपया सुनिश्चित करें कि आपका उत्तर इसके बिना उपयोगी है: लिंक के चारों ओर संदर्भ जोड़ें ताकि आपके साथी उपयोगकर्ताओं को कुछ पता चले कि यह क्या है और यह क्यों है, तो पृष्ठ के सबसे प्रासंगिक भाग को उद्धृत करें ' मामले में लक्ष्य पृष्ठ अनुपलब्ध होने पर पुनः लिंक करना। ऐसे लिंक जो किसी लिंक से बहुत कम हैं उन्हें हटाया जा सकता है।
बौम Augen mit

क्षमा करें, मैंने इसे उत्तर के रूप में पोस्ट करने का इरादा नहीं किया था, लेकिन यह अन्य उत्तरों से संबंधित नहीं है और मुझे नहीं पता कि इसे कहाँ रखा जाए
17'17

1
मैंने सुझाव के अनुसार पोस्ट को संपादित किया। मूल रूप से मैं सिर्फ एक अलग कोण (शायद) में योगदान करना चाहूंगा, लेकिन मुझे केवल एक डाउनवोट मिला और हमने अभी तक सामग्री के बारे में बात नहीं की, -1 क्या कृपया इसका कारण बता सकते हैं?
स्ट्रिशनल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.