2010-01-30 9 views
9

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

+0

java.util.UUID के मामले में मुझे निराशाजनक subclass करने में असमर्थता मिलती है। –

उत्तर

3

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

+0

विशेषता एक्स को एक ही चीज़ नहीं बना रहा है? – Dalius

+1

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

4

"क्यों स्ट्रिंग जावा में अंतिम है" सवाल में इस बारे में कुछ अच्छी विचार विमर्श कर रहे हैं: Why is String class declared final in Java?

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

2

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

इसके अलावा कक्षाएं हैं जो जावा में java.lang.String क्लास जैसे अपरिवर्तनीय हैं, इसे विस्तारित करना और इसके व्यवहार को बदलने से बड़ी गड़बड़ी हो सकती है!

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

+0

1. प्रश्न subclassing व्यवहार जोड़ने की अनुमति देने के बारे में है। मैं समझता हूं कि आप ओवरराइडिंग क्यों प्रतिबंधित करना चाहते हैं। 2. यदि कक्षा आपको लिखने के लिए 3 महीने लेती है, तो शायद यह बहुत अधिक तरीका है। – dsimcha

+0

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

3

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

0

मुझे लगता है कि यह निर्भर करता है।

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

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

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

0

जहां तक ​​मुझे पता है, यह invariants को बनाए रखने के बारे में है।

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

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

समस्या वास्तव में नहीं है जब कोई उपयोगकर्ता कक्षा को बढ़ाता है और केवल अपने सिस्टम में इसका उपयोग करता है, जो कि अपने सभी "गड़बड़" से अलग होता है। असली समस्या इस तथ्य के साथ है कि वर्ग/विधियों/विशेषताओं/वस्तुओं/... अलगाव में मौजूद नहीं है।

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

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

  • तरह विधि स्थिर होना चाहिए:

    वैसे, कुछ अन्य अपरिवर्तनशीलताओं तरह बातें शामिल हैं।

  • < > विधि < अन्य > एल्गोरिदम का उपयोग करता है।
  • यह < वर्ग > सूची कार्यान्वयन को < कुछ स्थान > वर्णित अनुसार सूचीबद्ध लिंक कार्यान्वयन का उपयोग करना चाहिए।

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

संबंधित मुद्दे