बहुत से लोग मानते हैं कि, अपरिवर्तनीय वर्ग बनाने के विपरीत final
है नहीं की आवश्यकता है।
अपरिवर्तनीय कक्षाएं बनाने के लिए मानक तर्क final
यह है कि यदि आप ऐसा नहीं करते हैं, तो उपवर्ग उत्परिवर्तन जोड़ सकते हैं, जिससे सुपरक्लास के अनुबंध का उल्लंघन हो सकता है। वर्ग के ग्राहक अपरिवर्तनीयता मानेंगे, लेकिन जब उनके नीचे से कुछ उत्परिवर्तित होगा तो आश्चर्य होगा।
यदि आप इस तर्क को उसके तार्किक चरम पर ले जाते हैं, तो सभी विधियाँ बनाई जानी चाहिए final
, क्योंकि अन्यथा एक उपवर्ग इस तरह से एक विधि को ओवरराइड कर सकता है जो उसके सुपरक्लास के अनुबंध के अनुरूप नहीं है। यह दिलचस्प है कि अधिकांश जावा प्रोग्रामर इसे हास्यास्पद के रूप में देखते हैं, लेकिन किसी तरह इस विचार के साथ ठीक हैं कि अपरिवर्तनीय कक्षाएं होनी चाहिए final
। मुझे संदेह है कि इसका जावा प्रोग्रामर के साथ कुछ ऐसा है जो सामान्य रूप से अपरिवर्तनीयता की धारणा के साथ पूरी तरह से सहज नहीं है, और शायद final
जावा में कीवर्ड के कई अर्थों से संबंधित कुछ अजीब तरह की सोच है ।
अपने सुपरक्लास के अनुबंध के अनुरूप कुछ ऐसा नहीं है जिसे कंपाइलर द्वारा हमेशा लागू किया जा सकता है या होना चाहिए। कंपाइलर आपके अनुबंध के कुछ पहलुओं को लागू कर सकता है (जैसे: तरीकों का एक न्यूनतम सेट और उनके प्रकार के हस्ताक्षर) लेकिन विशिष्ट अनुबंध के कई हिस्से हैं जो कंपाइलर द्वारा लागू नहीं किए जा सकते हैं।
अपरिवर्तनीयता एक वर्ग के अनुबंध का हिस्सा है। यह उन कुछ चीज़ों से थोड़ा अलग है, जिनका लोग अधिक उपयोग करते हैं, क्योंकि यह कहता है कि वर्ग (और सभी उपवर्ग) क्या नहीं कर सकते , जबकि मुझे लगता है कि अधिकांश जावा (और आमतौर पर ओओपी) प्रोग्रामर अनुबंधों के बारे में सोचते हैं। एक वर्ग क्या कर सकता है, वह नहीं जो वह नहीं कर सकता।
अपरिहार्यता भी केवल एक ही विधि से अधिक प्रभावित होती है - यह पूरे उदाहरण को प्रभावित करती है - लेकिन यह वास्तव में जावा के काम करने के तरीके equals
और तरीकों से बहुत अलग नहीं है hashCode
। उन दो विधियों में एक विशिष्ट अनुबंध होता है Object
। यह अनुबंध बहुत सावधानी से उन चीजों को देता है जो ये विधियां नहीं कर सकती हैं। इस अनुबंध को उपवर्गों में अधिक विशिष्ट बनाया गया है। ओवरराइड करना equals
या hashCode
अनुबंध का उल्लंघन करने वाले तरीके से करना बहुत आसान है । वास्तव में, यदि आप इन दो तरीकों में से केवल एक को दूसरे के बिना ओवरराइड करते हैं, तो संभावना है कि आप अनुबंध का उल्लंघन कर रहे हैं। तो चाहिए equals
और hashCode
घोषित किया गया है final
में Object
इस से बचने के लिए? मुझे लगता है कि अधिकांश यह तर्क देंगे कि उन्हें नहीं करना चाहिए। इसी तरह, अपरिवर्तनीय कक्षाएं बनाना आवश्यक नहीं हैfinal
।
कहा कि, आपकी अधिकांश कक्षाएं, अपरिवर्तनीय या नहीं, शायद होनी चाहिए final
। प्रभावी जावा दूसरा संस्करण देखें आइटम 17: "वंशानुक्रम के लिए डिज़ाइन और दस्तावेज़ या फिर इसे प्रतिबंधित करें"।
तो आपके चरण 3 का एक सही संस्करण होगा: "वर्ग को अंतिम बनाएं या, जब उपवर्ग के लिए डिज़ाइन किया जाए, तो स्पष्ट रूप से दस्तावेज़ दें कि सभी उपवर्गों को अपरिवर्तनीय होना चाहिए।"
java.math.BigInteger
वर्ग उदाहरण है, यह मान अपरिवर्तनीय है लेकिन यह अंतिम नहीं है।