वंशानुक्रम के लिए डिजाइनिंग अतिरिक्त लागत का कारण कैसे बन सकती है? [बन्द है]


12

इसलिए मैं csharpsealed class में एक से वारिस करना चाहता था और जल गया। जब तक आपके पास स्रोत तक पहुंच न हो, तब तक इसे हटाने का कोई तरीका नहीं है।

फिर यह सोचकर मुझे "क्यों sealedमौजूद है?"। 4 महीने पहले। मैं इसके बारे में कई बातें पढ़ने के बावजूद इसका पता नहीं लगा सका, जैसे:

मैंने तब से सभी को पचाने की कोशिश की है, लेकिन यह मेरे लिए बहुत ज्यादा है। आखिरकार, कल मैंने इसे फिर से आजमाया। मैंने उन सभी को फिर से स्कैन किया है, साथ ही कुछ और भी:

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

पुराने सवाल काफ़ी व्यापक है और व्यक्तिपरक थे। यह मूल रूप से पूछ रहा था:

  1. पुराने शीर्षक में: सील का उपयोग करने का एक अच्छा कारण
  2. शरीर में: सील किए गए वर्ग को ठीक से कैसे संशोधित किया जाए? विरासत के बारे में भूल जाओ? रचना का उपयोग करें?

लेकिन अब, यह समझना (जो मैंने कल नहीं किया था) कि यह सब sealedविरासत को रोक रहा है , और हमें वास्तव में विरासत पर रचना का उपयोग करना चाहिए , मुझे एहसास हुआ कि मुझे जो चाहिए वह व्यावहारिक उदाहरण था ।

मुझे लगता है कि मेरा सवाल यहाँ है (और वास्तव में हमेशा रहा है) श्री मिन्दोर ने मुझे एक चैट में सुझाव दिया था : वंशानुक्रम के लिए डिज़ाइन करना अतिरिक्त लागत का कारण कैसे हो सकता है?


5
सवाल काफी आक्रामक रूप से लिया गया है और एक शेख़ी की तरह लगता है। यदि आप प्रासंगिक और वस्तुनिष्ठ उत्तर चाहते हैं तो आपको इसे फिर से लिखना चाहिए।
व्यंग्यात्मक

11
देखें कि फ्रेमवर्क क्लासेस सील के इतने सारे क्यों हैं? एरिक लिपर्ट द्वारा। वह कक्षाओं को सील करने के लिए कई अच्छे कारण प्रदान करता है।
रॉबर्ट हार्वे

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

4
@ कवास वह हो सकता है, या आप उस लेख को पढ़ सकते हैं जो उसने जोड़ा है जो इसे विस्तार से बताता है। वह सिर्फ अपनी टिप्पणी के साथ उस लेख को सारांशित कर रहे थे।
सेवी

7
क्षमा करें, लेकिन मैं वह नहीं हूं, जो यहां रेंटिंग कर रहा हूं। आपके प्रश्न का उत्तर बहुत सरल है: जब आप विरासत का समर्थन नहीं करना चाहते हैं तो एक वर्ग को सील करें। बस।
रॉबर्ट हार्वे

जवाबों:


27

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

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

मान लीजिए कि एक डेवलपर ने .Net कोर क्लास का विस्तार किया (क्योंकि सील मौजूद नहीं थी) और इसे पूरी तरह से काम करने के लिए मिला। डेवलपर के लिए याय। डेवलपर ग्राहक को उत्पाद वितरित करता है। डेवलपर का ऐप शानदार काम करता है। ग्राहक खुश है। ज़िंदगी अच्छी है।

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

किसे दोष मिलता है?

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

उपयोग sealedकरने से उपरोक्त परिदृश्य पूरी तरह से समाप्त नहीं होता है, लेकिन यह मदद करता है।


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

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

2
@Cawas विशाल विरासत में मिला सबसे डेवलपर्स द्वारा लिखे कक्षाओं के बहुमत की जरूरत कभी नहीं होगा करने के लिए किया जाएगा, और समर्थन विरासत में लिखा नहीं कर रहे हैं। यह जल्दी और प्रभावी ढंग से कोड के पाठकों / उपयोगकर्ताओं को संदेश दिया जा सकता है sealed। यदि यह वास्तव में डिफ़ॉल्ट विकल्प था, तो इसका मतलब होगा कि यदि कोई व्यक्ति किसी प्रकार से विरासत में मिला था, तो उन्हें पता होगा कि यह समर्थन करने के लिए बनाया गया है।
सेवी

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

1
सुरक्षा भी इसका उपयोग करने का एक कारण है! एक सैंडबॉक्स वाले एप्लिकेशन पर विचार करें जो एक फ़ाइल तक पहुंचने की कोशिश कर रहा है। सैंडबॉक्स फाइलनाम-स्ट्रिंग्स का परीक्षण कर सकता है, लेकिन क्या होगा यदि एक हमलावर आपको एक उत्परिवर्तित भेज सकता है Stringऔर फिर वे सुरक्षा-जांच के बाद इसे I / O से पहले म्यूट कर सकते हैं? मेरा मानना है कि यही कारण है कि जावा के परिदृश्य के प्रकार है Stringचिह्नित है final(के समान sealed) और मुझे यकीन है यही तर्क कुछ सी # निर्णय मज़बूत बनाता है।
दरियाई

23

sealedयह इंगित करने के लिए उपयोग किया जाता है कि कक्षा के लेखक ने इसे विरासत में प्राप्त करने के लिए डिज़ाइन नहीं किया है। कुछ कम नहीं, कुछ ज्यादा नहीं।

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

उस मामले की कल्पना करें जहां वर्ग CustomBoeing787उत्पन्न होता है Airliner। यह CustomBoeing787कुछ संरक्षित तरीकों को ओवरराइड करता है Airliner, लेकिन उन सभी को नहीं। यदि डेवलपर के पास पर्याप्त समय है और यह इसके लायक है, तो वह यह सुनिश्चित करने के लिए कक्षा का परीक्षण कर सकता है कि सब कुछ अपेक्षित रूप से काम करता है, यहां तक ​​कि जब गैर-ओवरराइडन तरीकों को बुलाया जाता है (उदाहरण के लिए संरक्षित बसने वाले जो वस्तु की स्थिति को बदलते हैं)। यदि एक ही डेवलपर (1) के पास समय नहीं है, (2) अपने बॉस / ग्राहक के अतिरिक्त सैकड़ों या हजारों डॉलर खर्च नहीं करना चाहता है, या (3) वह अतिरिक्त कोड नहीं लिखना चाहता है जो वह नहीं करता है अभी (YAGNI) की जरूरत है, तो वह कर सकता है:

  • या तो कोड को जंगली के रूप में जारी करें, यह देखते हुए कि यह उन प्रोग्रामरों की चिंता है जो इस परियोजना को बनाए रखेंगे, बाद में संभावित बगों की देखभाल करेंगे,

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

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


सब ठीक है ... क्षमा करें अगर मैं फिर से आक्रामक आवाज़ करता हूं, लेकिन मैं यहां स्पष्ट और मुखर होना चाहता हूं ... मैं केवल यह समझ सकता हूं कि आपने सिर्फ 2 तरीकों में से क्या लिखा है, यदि आप tl;drयहां लिखना चाहते थे । यह या तो "नहीं, एक भी अच्छा कारण नहीं है" , या "मुझे लगता है कि कोई अच्छा कारण नहीं है, लेकिन मैं भी नहीं जानता।" । मेरे लिए "कोई निश्चित जवाब नहीं" या तो उनमें से एक है।
cregox

6
sealedयह इंगित करने के लिए उपयोग किया जाता है कि कक्षा के लेखक ने इसे विरासत में प्राप्त करने के लिए डिज़ाइन नहीं किया है। यही आपका एक अच्छा कारण है।
रॉबर्ट हार्वे

यह एक अच्छा कारण के रूप में आप रोशनी के बिना एक साइकिल दे रहा है और लागू कर रहा है, किसी भी तरह, आप रोशनी नहीं जोड़ सकते।
cregox

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

1
सुरक्षा भी इसका उपयोग करने का एक कारण है! एक सैंडबॉक्स वाले एप्लिकेशन पर विचार करें जो एक फ़ाइल तक पहुंचने की कोशिश कर रहा है। सैंडबॉक्स फाइलनाम-स्ट्रिंग्स का परीक्षण कर सकता है, लेकिन क्या होगा यदि एक हमलावर आपको एक उत्परिवर्तित भेज सकता है Stringऔर फिर वे सुरक्षा-जांच के बाद इसे I / O से पहले म्यूट कर सकते हैं? मेरा मानना है कि यही कारण है कि जावा के परिदृश्य के प्रकार है Stringचिह्नित है final(के समान sealed) और मुझे यकीन है यही तर्क कुछ सी # निर्णय मज़बूत बनाता है।
दरियाई

4

जब एक वर्ग को सील किया जाता है, तो वह उस प्रकार का उपयोग करके कोड को यह जानने की अनुमति देता है कि वे क्या व्यवहार कर रहे हैं।

अब C # stringमें sealed, आप इससे विरासत में नहीं मिल सकते हैं, लेकिन चलो एक दूसरे के लिए मान लेते हैं कि ऐसा नहीं था। यदि आपने किया, तो कोई इस तरह एक वर्ग लिख सकता है:

public class EvilString// : String
{
    public override string ToString()
    {
        throw new Exception("I'm mean");
    }
    public override bool Equals(object obj)
    {
        return false;
    }
    public override int GetHashCode()
    {
        return 0;
    }
}

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

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


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

3
@ कावा और अगर एक अप्रत्याशित समय पर एक अपवाद को फेंक दिया जाता है और एक परिणाम के रूप में एक संसाधन लीक हो जाता है, या एक वर्ग अनिश्चित स्थिति में छोड़ दिया जाता है और अनुचित तरीके से कार्य करता है? यह मामला थोड़ा मूर्खतापूर्ण है, लेकिन यह आसानी से ऐसा मामला हो सकता है कि कोई ऐसा कार्यान्वयन लिखता है जो उन्हें लगता है कि समझदार है, लेकिन कभी-कभी यह तब नहीं फेंकता है जब तक कि कुछ मूल्यों के साथ काम नहीं करना चाहिए। जब भाषा कोड काम नहीं करेगा तब वे शिकायत करेंगे। यह सिर्फ लोगों को उन चीजों को न करने के लिए बेहतर है जो भाषा का समर्थन करने में सक्षम नहीं होगी।
18

किसी भी मामले में आप एक कंपाइलर बनाने की बात कर रहे हैं। कई ऐसी sealedविशेषताएं हैं जिनमें अंतर्निहित हैं जो हमारे उपयोग के लिए उजागर नहीं हैं। यह अभी भी स्पष्ट नहीं करता है कि इस तरह के एक संकीर्ण दायरे के बाहर इसका उपयोग क्यों करें और संकलक कोड के रूप में संकीर्ण होने के नाते , sealedअस्तित्व की व्याख्या भी नहीं करता है।
cregox

2
@ कावासा stringप्रकार संकलक कोड नहीं है। यह भाषा कोड का हिस्सा है। पूरी तरह से अलग। किसी भी मामले में, मैंने सिर्फ एक उदाहरण चुना। आप पूरे BCL में किसी भी मोहरबंद वर्ग को चुन सकते हैं और उदाहरण के तौर पर उसका उपयोग कर सकते हैं।
सेवी

4
@ कावासा: मुझे लगता है कि जो कुछ आपको याद आ रहा है वह ग्राहक सहायता पहलू है। यदि आप किसी वर्ग को अंतर्निहित होने की अनुमति देते हैं, तो ग्राहक उससे विरासत में प्राप्त करने जा रहे हैं, और तब वे आपको कॉल करेंगे जब यह टूट जाएगा। आप दिन भर उन्हें बता सकते हैं कि वे अपने जोखिम पर उस वर्ग से विरासत में मिले हैं , लेकिन आप अभी भी कॉल प्राप्त करने जा रहे हैं, क्योंकि आपने उन्हें इससे विरासत में प्राप्त करने की अनुमति दी है, इसलिए वे मानते हैं कि ऐसा करना सुरक्षित है।
रॉबर्ट हार्वे

3

क्या सील का उपयोग करने का कोई अच्छा कारण है?

Enh? प्रायः नहीं। मैं केवल सील का उपयोग करेगा जब मेरे पास एक अपरिवर्तनीय प्रकार (या कुछ अन्य सीमा) है जो वास्तव में अपरिवर्तनीय रहने की आवश्यकता है और मैं सिस्टम में सूक्ष्म, भयावह बग को पेश किए बिना उस आवश्यकता को पूरा करने के लिए इनहेरिटर्स पर भरोसा नहीं कर सकता।

मान लीजिए कि सील का उपयोग करने का एक अच्छा कारण है और हमें इसे हर चीज के लिए डिफ़ॉल्ट के रूप में उपयोग करना चाहिए, हम विरासत के साथ क्या करते हैं?

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

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


मेरे लिए, यह और "ग्राहकों को विरासत का समर्थन करने से बचने के लिए" कि रॉबर्ट विस्तृत नहीं करना चाहते हैं सबसे आशाजनक उत्तर हैं ... शायद आप उन मामलों पर अधिक विस्तृत कर सकते हैं जहां आप उपयोग करते हैं sealed, कृपया?
cregox

@ कवास - मुझे यकीन नहीं है कि मैं अच्छा कर सकता हूँ। मैं शायद ही कभी ऐसा करता हूं, और यह अक्सर एक ट्रेडऑफ़ है जहां गारंटी है कि कुछ अपरिवर्तनीय रहता है (प्रदर्शन अनुकूलन करने के लिए, डिजाइन सरलीकरण) ऑब्जेक्ट से विरासत में प्राप्त करने में असमर्थता है।
तेलस्टिन

यह अच्छा है। डुबो दिया पहले से ही इसे डुबो दिया! : पी उत्तर के लिए बहुत बहुत धन्यवाद। और आप मेरी विशेषज्ञता के बारे में मेरे "सूक्ष्म संकेत" लेने वाले एकमात्र व्यक्ति थे। लगता है जैसे लोग मुझे अधिक जानते थे, मुझे नहीं पता ... लेकिन मैं चाहता हूं कि "बस कोडिंग" मुझे इस चट्टान से बाहर ले जाएगी। हो सकता है कि मैं उन अवधारणाओं को किसी तरह से लागू करूं, सिर्फ प्रक्रियात्मक रूप से नहीं जैसा कि मुझे शायद करना चाहिए।
cregox

3

सबसे पहले, आपको एरिक लिपर्ट के पोस्ट को पढ़ना चाहिए कि Microsoft उनकी कक्षाओं को क्यों सील करते हैं।

http://blogs.msdn.com/b/ericlippert/archive/2004/01/22/61803.aspx

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

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


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

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

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

2

मुझे लगता है कि इस प्रश्न का वस्तुनिष्ठ उत्तर नहीं है और यह सब आपके दृष्टिकोण पर निर्भर करता है।

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

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


यही बेहतर है! यह एक अच्छा कारण हो सकता है ... "क्योंकि लोग इसे बंद करना चाहते हैं"। और यह भी है कि मैं सवाल में क्या कहना चाह रहा हूं: लगता है कि C ++ में गैर-आभासी कक्षाएं ओवरराइड की जा सकती हैं। sealedनहीं कर सकता। हम उनसे विरासत में कैसे ले सकते हैं? मैंने पढ़ा है कि हम नहीं कर सकते। कभी। मुझे नहीं पता। मैं इस विषय पर 4 महीने से आगे पीछे हूं, क्योंकि मैंने पहली बार सील के बारे में सुना था। और मुझे अभी भी नहीं पता कि यह कैसे करना है, जब मुझे सील किए गए वर्ग पर कुछ भी संशोधित करने की आवश्यकता होती है। इसलिए, मुझे "इसे खोलने के लिए कोई विकल्प नहीं" दिखाई दे रहा है!
cregox

4
यह नहीं है क्यों डिफ़ॉल्ट रूप से C ++ वर्ग विधियाँ आभासी नहीं हैं। एक विधि को आभासी बनाने का मतलब है कि विधि लुकअप टेबल पर अतिरिक्त ओवरहेड होना चाहिए, और C ++ में दर्शन है जो आप केवल ओवरहेड के लिए भुगतान करते हैं जब आप सुविधा चाहते हैं।
माइकल शॉ

@Ptolemy ठीक है, मैंने इसे हटा दिया। मुझे इसे कभी नहीं लिखना चाहिए था, क्योंकि मुझे पता था कि लोग इसके बारे में शिकायत करना शुरू करते हैं।
व्यंग्यात्मक

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

IMO यह निजी / संरक्षित / सार्वजनिक बहसों के समान है जब यह एपीआई की बात आती है: यह दृढ़ता से इस बात पर निर्भर करता है कि कौन वर्ग को नियंत्रित करता है, कौन वर्ग को विरासत में देना चाहता है, दोनों के बीच संचार, और कितनी बार नए संस्करण सामने आते हैं।
डेरेन

-2

सी # में सील के साथ समस्या यह है कि इसके बजाय अंतिम है। 7 साल के C # कमर्शियल डेवलपमेंट में, मैंने इसे इस्तेमाल करने का एकमात्र स्थान Microsoft .NET क्लासेस पर देखा है जहाँ मुझे लगता है कि मेरे पास समायोजित व्यवहार को लागू करने के लिए एक फ्रेमवर्क क्लास का विस्तार करने का एक वैध कारण था, और क्योंकि क्लास को सील कर दिया गया था, इसलिए मैं नहीं कर सका। ।

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

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

मैं देख सकता हूं कि अब तक तीन तर्क दिए गए हैं जो अब तक सीलबंद हैं।

  1. तर्क 1 यह है कि यह बगों के एक स्रोत को समाप्त करता है जब लोग कक्षाओं से विरासत में प्राप्त होते हैं और फिर आंतरिक रूप से ठीक से समझे बिना उस वर्ग के आंतरिक तक पहुंच बढ़ाते हैं।

  2. तर्क 2 यह है कि यदि आप एक Microsoft वर्ग का विस्तार करते हैं और तब Microsoft उस वर्ग में बग फिक्स लागू करता है, लेकिन आपका विलोपन उस बग पर निर्भर करता है, तो आपका कोड अब टूट गया है, Microsoft को दोष मिलता है, और सील रोकता है

  3. तर्क 3 यह है कि वर्ग के विकासक के रूप में, मेरी अपनी पसंद है कि क्या आप इसे कक्षा के मेरे डिजाइन के भाग के रूप में विस्तारित कर सकते हैं।

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

मैं समझता हूं कि arg 2 का तथ्यात्मक आधार कहां से आता है। विशेष रूप से जब Microsoft ने विकृत कॉल की पहचान करने के लिए win32 एपीआई कॉल पर अतिरिक्त ओएस चेक लगाए, जिसमें विंडोज एनटी की तुलना में विंडोज एक्सपी की सामान्य स्थिरता में सुधार हुआ है, लेकिन अल्पावधि लागत पर विंडोज एक्सपी जारी होने पर कई ऐप टूट गए थे। Microsoft ने इन जाँचों को कहने के लिए 'नियम' डालकर इसे हल किया, जब ऐप X इस नियम को तोड़ता है, तो यह एक ज्ञात बग है

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

तर्क 3 एकमात्र तर्क है जिसमें किसी भी पदार्थ को अपने आप को सही ठहराने के लिए है। लेकिन यह अभी भी कमजोर है। यह सिर्फ कोड के पुन: उपयोग के दाने के खिलाफ जाता है।


2
/ मुझे microsoft के लिए एक ईमेल भेजता है, कृपया आप मेरे लिए दसवीं कक्षा को अनसॉल्व कर सकते हैं और .NET की एक नई रिलीज़ को शिप कर सकते हैं। तरह का संबंध है, .... जैसा मैंने कहा, वाणिज्यिक विकास में केवल एक बार मैंने एक सील वर्ग देखा है, इसे अनसुना करना संभव नहीं था।
माइकल शॉ

6
It is impossible to write a class thinking about every possible way it could be used- यही कारण है कि कई फ्रेमवर्क वर्गों को सील कर दिया गया है ... यह हर संभव तरीके के बारे में सोचने की आवश्यकता को समाप्त करता है जिससे कोई वर्ग का विस्तार कर सकता है।
रॉबर्ट हार्वे

5
यदि आप इसे अनसुना कर सकते हैं, तो इसे सील करने में कोई मतलब नहीं होगा, क्या वहाँ होगा?
रॉबर्ट हार्वे

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

2
@ कव्वा: आप मुश्किल में हैं।
रॉबर्ट हार्वे

-7

मैं केवल उन sealedकक्षाओं पर कीवर्ड का उपयोग करता हूं जिनमें केवल स्थिर विधियां हैं।


9
फिर staticइसके बजाय सिर्फ कक्षा को ही क्यों चिन्हित किया जाए ?
सेवी

@ सरस्वती ... अच्छी बात है।
व्लादिमीर कोकजेनिक

-8

जैसा कि मेरे प्रश्न से स्पष्ट है, मैं यहाँ कोई विशेषज्ञ नहीं हूँ। लेकिन मुझे sealedयहां तक ​​मौजूद होने का कोई कारण नहीं दिखता ।

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

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

हो सकता है कि कोई कीवर्ड हो stable, इसलिए लोगों को पता होगा कि यह उससे सुरक्षित है।


2
"समस्या हल" - बिल्कुल।
रॉबर्ट हार्वे

@RobertHarvey यह हल नहीं है, जैसा कि अगले पैराग्राफ में बताया गया है।
cregox

8
आप सिर्फ इसलिए पागल हैं क्योंकि आप कक्षा का विस्तार नहीं कर सकते। इसका मतलब यह नहीं है कि sealedयह फ्रेमवर्क डिजाइनरों के लिए एक उपयोगी उपकरण नहीं है। एक फ्रेम में कक्षाएं ब्लैक बॉक्स होनी चाहिए; आपको किसी वर्ग के आंतरिक लोगों के बारे में पता नहीं होना चाहिए ताकि वे इसका सही उपयोग कर सकें। फिर भी यह वही है जो विरासत मांगता है।
रॉबर्ट हार्वे

मैंने कभी नहीं कहा कि यह उपयोगी नहीं है। मैं कहता हूं कि मुझे इसका उपयोग दिखाई नहीं दे रहा है, और बताते हैं कि क्यों। कृपया, मैं आपसे भीख माँग रहा हूँ, मुझे इसका उपयोग करने का एक अच्छा कारण दीजिए! यहां तक ​​कि अगर यह सिर्फ "क्योंकि मैं एक बंद डिजाइन पैटर्न का पालन करना चाहता हूं", तो यह ठीक है। मैं स्पष्ट रूप से किसी को भी यह कारण नहीं देता।
cregox

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