आप एक स्थिर विधि को अंतिम बनाने के बारे में सोचने की स्थिति में खुद को पा सकते हैं, निम्नलिखित पर विचार कर सकते हैं:
निम्नलिखित कक्षाएं होने:
class A {
static void ts() {
System.out.print("A");
}
}
class B extends A {
static void ts() {
System.out.print("B");
}
}
अब इन विधियों को कॉल करने का 'सही' तरीका होगा
A.ts();
B.ts();
जिसके परिणामस्वरूप AB
आप उदाहरणों पर विधियों को भी कॉल कर सकते हैं:
A a = new A();
a.ts();
B b = new B();
b.ts();
जिसके परिणामस्वरूप भी होगा AB
।
अब निम्नलिखित पर विचार करें:
A a = new B();
a.ts();
वह छपेगा A
। जब से आप वास्तव में कक्षा की वस्तु हैं, तब आपको आश्चर्य हो सकता है B
। लेकिन चूंकि आप इसे एक प्रकार के संदर्भ से बुला रहे हैं A
, यह कॉल करेगा A.ts()
। आप B
निम्नलिखित कोड के साथ प्रिंट कर सकते हैं :
A a = new B();
((B)a).ts();
दोनों ही मामलों में आपके पास मौजूद वस्तु वास्तव में कक्षा से है B
। लेकिन ऑब्जेक्ट को इंगित करने वाले पॉइंटर के आधार पर, आप विधि को A
या उससे कॉल करेंगे B
।
अब मान लेते हैं कि आप क्लास के डेवलपर हैं A
और आप सब-क्लासिंग की अनुमति देना चाहते हैं। लेकिन आप वास्तव में विधि चाहते हैं ts()
, जब भी बुलाया जाता है, यहां तक कि एक उपवर्ग से भी, यही वह है जो आप इसे करना चाहते हैं और एक उपवर्ग संस्करण द्वारा छिपाया नहीं जाना चाहिए। तब आप इसे बना सकते थे final
और इसे उपवर्ग में छिपे रहने से रोक सकते थे। और आप यह सुनिश्चित कर सकते हैं कि निम्न कोड आपकी कक्षा से विधि को बुलाएगा A
:
B b = new B();
b.ts();
ठीक है, मान लिया कि किसी तरह का निर्माण किया है, लेकिन यह कुछ मामलों के लिए समझ में आ सकता है।
आपको इंस्टेंस पर स्थिर तरीकों को नहीं बल्कि सीधे कक्षाओं पर कॉल करना चाहिए - फिर आपको वह समस्या नहीं होगी। उदाहरण के लिए इंटेलीजे आईडीईए आपको एक चेतावनी भी दिखाएगा, यदि आप एक उदाहरण पर एक स्थिर विधि कहते हैं और साथ ही यदि आप एक स्थिर प्रदर्शन को अंतिम बनाते हैं।