कई लोगों का मानना है कि एक अपरिवर्तनीय वर्ग final
आवश्यक नहीं है।
अपरिवर्तनीय कक्षाएं final
बनाने के लिए मानक तर्क यह है कि यदि आप ऐसा नहीं करते हैं, तो उप-वर्ग उत्परिवर्तन जोड़ सकते हैं, जिससे सुपरक्लास के अनुबंध का उल्लंघन होता है। कक्षा के ग्राहक अपरिवर्तनीयता मानेंगे, लेकिन कुछ आश्चर्यचकित होगा जब कुछ उनके नीचे से उत्परिवर्तित होगा।
आप अपने तार्किक चरम पर इस तर्क को ले, तो सभी तरीकों final
बनाया जाना चाहिए, के रूप में अन्यथा एक उपवर्ग एक तरीका है कि अपने सुपर क्लास के अनुबंध के अनुरूप नहीं है में एक विधि रद्द कर सकते थे। यह दिलचस्प है कि अधिकांश जावा प्रोग्रामर इसे हास्यास्पद मानते हैं, लेकिन इस विचार के साथ किसी भी तरह ठीक है कि अपरिवर्तनीय कक्षाएं final
होनी चाहिए। मुझे संदेह है कि जावा प्रोग्रामर के साथ इसका कुछ संबंध नहीं है, जो सामान्य रूप से अपरिवर्तनीयता की धारणा के साथ पूरी तरह से सहज नहीं है, और शायद जावा में final
कीवर्ड के कई अर्थों से संबंधित कुछ प्रकार की अस्पष्ट सोच है।
आपके सुपरक्लास के अनुबंध के अनुरूप कुछ ऐसा नहीं है जो हमेशा संकलक द्वारा लागू किया जा सकता है या इसे लागू किया जाना चाहिए। कंपाइलर आपके अनुबंध के कुछ पहलुओं को लागू कर सकता है (उदाहरण: विधियों का न्यूनतम सेट और उनके प्रकार के हस्ताक्षर) लेकिन ठेठ अनुबंधों के कई भाग हैं जिन्हें संकलक द्वारा लागू नहीं किया जा सकता है।
अपरिवर्तनीयता कक्षा के अनुबंध का हिस्सा है। यह उन चीज़ों में से कुछ अलग है जो लोगों का अधिक उपयोग किया जाता है, क्योंकि यह कहता है कि कक्षा (और सभी उप-वर्ग) नहीं कर सकते हैं, जबकि मुझे लगता है कि अधिकांश जावा (और आमतौर पर ओओपी) प्रोग्रामर अनुबंध के बारे में सोचते हैं क्या कर सकते हैं, क्या नहीं कर सकता है।
अचल स्थिति भी बस एक ही विधि से अधिक प्रभावित करता है यह पूरे उदाहरण — को प्रभावित करता है, लेकिन यह वास्तव में बहुत तरह से equals
और hashCode
जावा काम की तुलना में अलग नहीं है —। उन दो विधियों के पास Object
में एक विशिष्ट अनुबंध है। यह अनुबंध बहुत सावधानीपूर्वक बताता है कि इन विधियों नहीं कर सकते हैं। यह अनुबंध उप-वर्गों में अधिक विशिष्ट बना दिया गया है। अनुबंध का उल्लंघन करने वाले तरीके से equals
या hashCode
को ओवरराइड करना बहुत आसान है। वास्तव में, यदि आप बिना किसी अन्य तरीकों में से केवल एक को ओवरराइड करते हैं, तो संभावना है कि आप अनुबंध का उल्लंघन कर रहे हैं। तो equals
और hashCode
को final
Object
में यह से बचने के लिए घोषित किया जाना चाहिए? मुझे लगता है कि ज्यादातर बहस करेंगे कि उन्हें नहीं करना चाहिए। इसी प्रकार, अपरिवर्तनीय कक्षाएं final
बनाने के लिए आवश्यक नहीं है।
यह कहा गया है कि, आपकी अधिकांश कक्षाएं, अपरिवर्तनीय या नहीं, शायद final
होनी चाहिए। प्रभावी जावा द्वितीय संस्करण आइटम 17: "विरासत के लिए डिज़ाइन और दस्तावेज़ या अन्यथा इसे प्रतिबंधित करें"।
तो आपके चरण 3 का एक सही संस्करण होगा: "कक्षा को अंतिम बनाएं या उप-वर्गीकरण के लिए डिज़ाइन करते समय, स्पष्ट रूप से दस्तावेज करें कि सभी उप-वर्गों को अपरिवर्तनीय होना जारी रखना चाहिए।"
'java.math.BigInteger' वर्ग उदाहरण है, यह मान अपरिवर्तनीय हैं लेकिन यह अंतिम नहीं है। –
@ नंदकुमार यदि आपके पास 'बिगइंटर' है, तो आप नहीं जानते कि यह अपरिवर्तनीय है या नहीं। यह एक गड़बड़ डिजाइन है।/'java.io.File' एक और दिलचस्प उदाहरण है। –
सबक्लास को विधियों को ओवरराइड करने की अनुमति न दें - ऐसा करने का सबसे आसान तरीका कक्षा को अंतिम घोषित करना है। एक और परिष्कृत दृष्टिकोण कन्स्ट्रक्टर को निजी बनाने और कारखाने के तरीकों में उदाहरण बनाने के लिए है - https://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html –