जावा 8 स्थिर इंटरफ़ेस विधियों की अनुमति देता है
जावा 8 के साथ, इंटरफेस में स्थिर तरीके हो सकते हैं। उनके पास ठोस आवृत्ति विधियाँ भी हो सकती हैं, लेकिन उदाहरण क्षेत्र नहीं।
यहाँ वास्तव में दो प्रश्न हैं:
- बुरे पुराने दिनों में, इंटरफेस में स्थिर तरीके क्यों नहीं हो सकते हैं?
- स्थैतिक तरीकों को ओवरराइड क्यों नहीं किया जा सकता है?
इंटरफेस में स्थैतिक तरीके
कोई मजबूत तकनीकी कारण नहीं था कि इंटरफेस पिछले संस्करणों में स्थिर तरीके क्यों नहीं हो सकते थे। यह एक नकली प्रश्न के पोस्टर द्वारा अच्छी तरह से अभिव्यक्त किया गया है । स्टैटिक इंटरफ़ेस विधियों को शुरू में एक छोटी भाषा में बदलाव के रूप में माना जाता था , और फिर उन्हें जावा 7 में जोड़ने के लिए एक आधिकारिक प्रस्ताव था, लेकिन बाद में अप्रत्याशित जटिलताओं के कारण इसे हटा दिया गया था ।
अंत में, जावा 8 ने स्थैतिक इंटरफ़ेस विधियों के साथ-साथ डिफ़ॉल्ट कार्यान्वयन के साथ ओवरराइड-सक्षम इंस्टेंस विधियों को पेश किया। वे अभी भी उदाहरण क्षेत्रों नहीं हो सकता है। ये विशेषताएं लंबोदर अभिव्यक्ति समर्थन का हिस्सा हैं, और आप जेएसआर 335 के भाग एच में उनके बारे में अधिक पढ़ सकते हैं ।
स्थैतिक तरीकों को ओवरराइड करना
दूसरे प्रश्न का उत्तर थोड़ा अधिक जटिल है।
संकलित तरीकों को संकलित समय पर resolvable हैं। डायनेमिक डिस्पैच उदाहरण के तरीकों के लिए समझ में आता है, जहां कंपाइलर ठोस प्रकार के ऑब्जेक्ट को निर्धारित नहीं कर सकता है, और इस प्रकार, आह्वान करने की विधि को हल नहीं कर सकता है। लेकिन एक स्थैतिक विधि को लागू करने के लिए एक वर्ग की आवश्यकता होती है, और चूंकि उस कक्षा को सांख्यिकीय रूप से जाना जाता है - संकलन समय - गतिशील प्रेषण अनावश्यक है।
उदाहरण के तरीके कैसे काम करते हैं, इस पर थोड़ा पृष्ठभूमि यह समझने के लिए आवश्यक है कि यहां क्या हो रहा है। मुझे यकीन है कि वास्तविक कार्यान्वयन काफी अलग है, लेकिन मुझे अपनी पद्धति की धारणा को स्पष्ट करने दें, जो कि मॉडल ने व्यवहार को सटीक रूप से देखा है।
यह बताएं कि प्रत्येक वर्ग के पास एक हैश तालिका है जो विधि को लागू करने के लिए कोड के एक वास्तविक भाग के लिए हस्ताक्षर (नाम और पैरामीटर प्रकार) को मैप करता है। जब वर्चुअल मशीन एक उदाहरण पर एक विधि को लागू करने का प्रयास करती है, तो वह अपनी कक्षा के लिए ऑब्जेक्ट पर सवाल उठाती है और कक्षा की तालिका में अनुरोधित हस्ताक्षर को देखती है। यदि एक विधि निकाय पाया जाता है, तो इसे लागू किया जाता है। अन्यथा, कक्षा का मूल वर्ग प्राप्त किया जाता है, और लुकअप को वहां दोहराया जाता है। यह विधि प्राप्त होने तक आगे बढ़ता है, या कोई अधिक मूल वर्ग नहीं हैं - जिसके परिणामस्वरूप ए NoSuchMethodError
।
यदि एक सुपरक्लास और एक उपवर्ग दोनों में एक ही विधि हस्ताक्षर के लिए अपनी तालिकाओं में एक प्रविष्टि है, तो उप-वर्ग का संस्करण पहले सामने आया है, और सुपरक्लास के संस्करण का उपयोग कभी नहीं किया गया है - यह एक "ओवरराइड" है।
अब, मान लीजिए कि हम ऑब्जेक्ट इंस्टेंस को छोड़ देते हैं और बस एक उपवर्ग के साथ शुरू करते हैं। रिज़ॉल्यूशन ऊपर के रूप में आगे बढ़ सकता है, जिससे आपको "ओवररिडेबल" स्थिर विधि मिल जाएगी। संकल्प सभी संकलन-समय पर हो सकता है, हालांकि, चूंकि संकलक एक ज्ञात वर्ग से शुरू हो रहा है, बजाय इसके वर्ग के किसी अनिर्दिष्ट प्रकार के ऑब्जेक्ट को क्वेरी करने के लिए रनटाइम तक प्रतीक्षा करने के बजाय। एक स्थिर विधि को "ओवरराइडिंग" करने का कोई मतलब नहीं है क्योंकि एक हमेशा उस वर्ग को निर्दिष्ट कर सकता है जिसमें वांछित संस्करण होता है।
निर्माता "इंटरफेस"
यहां प्रश्न के हाल के संपादन को संबोधित करने के लिए थोड़ी अधिक सामग्री है।
ऐसा लगता है कि आप प्रत्येक क्रियान्वयन के लिए एक कंस्ट्रक्टर जैसी विधि को प्रभावी ढंग से लागू करना चाहते हैं IXMLizable
। एक मिनट के लिए इंटरफ़ेस के साथ इसे लागू करने की कोशिश करने के बारे में भूल जाओ, और यह दिखावा करो कि आपके पास कुछ कक्षाएं हैं जो इस आवश्यकता को पूरा करती हैं। आप इसका उपयोग कैसे करेंगे?
class Foo implements IXMLizable<Foo> {
public static Foo newInstanceFromXML(Element e) { ... }
}
Foo obj = Foo.newInstanceFromXML(e);
चूंकि आपको Foo
नई वस्तु को "निर्माण" करते समय स्पष्ट रूप से ठोस नाम देना है , इसलिए संकलक यह सत्यापित कर सकता है कि उसके पास वास्तव में आवश्यक फैक्ट्री विधि है। और अगर ऐसा नहीं है, तो क्या? मैं एक को लागू कर सकते हैं IXMLizable
कि "निर्माता" का अभाव है, और मैं एक उदाहरण बना सकते हैं और अपने कोड में इसे पारित, यह है एक IXMLizable
सभी आवश्यक इंटरफेस के साथ।
निर्माण कार्यान्वयन का हिस्सा है, न कि इंटरफ़ेस। इंटरफ़ेस के साथ सफलतापूर्वक काम करने वाला कोई भी कोड कंस्ट्रक्टर की परवाह नहीं करता है। किसी भी कोड को कंस्ट्रक्टर के बारे में परवाह करने के लिए कंक्रीट प्रकार को जानने की जरूरत है, और इंटरफ़ेस को अनदेखा किया जा सकता है।