2016-04-27 7 views
7

जावा 8 में डिफ़ॉल्ट विधि बनाते समय, कुछ Object विधियों को डिफ़ॉल्ट विधि से कॉल करने योग्य नहीं हैं। उदाहरण के लिए:क्यों कुछ ऑब्जेक्ट विधियां डिफ़ॉल्ट विधियों से कॉल करने योग्य नहीं हैं?

interface I { 
    default void m() { 
     this.toString(); // works. 
     this.clone(); // compile-time error, "The method clone() is undefined for the type I" 
     this.finalize(); // same error as above. 
    } 
} 

ऐसा लगता है कि clone() और finalize()Object से केवल तरीकों कि अनुमति नहीं है कर रहे हैं। संयोग से, ये Object की एकमात्र विधियां हैं जो संरक्षित हैं, लेकिन यह प्रश्न विशेष रूप से डिफ़ॉल्ट तरीकों के संबंध में है, क्योंकि उन्हें java.lang.Object का विस्तार करने वाले वर्गों द्वारा विरासत में प्राप्त किया जाएगा। इसका कारण क्या है?

+1

संभावित डुप्लिकेट [क्लोन() विधि java.lang.Object में संरक्षित क्यों है?] (Http://stackoverflow.com/questions/1138769/why-is-the-clone-method- संरक्षित-in- जावा-लैंग-ऑब्जेक्ट) – Sean

+1

@SPrashad मैं असहमत हूं। उस प्रश्न के साथ कुछ भी नहीं है कि यह इंटरफ़ेस की डिफ़ॉल्ट विधि में क्यों कॉल करने योग्य नहीं है। – rgettman

उत्तर

8

यह एक संयोग नहीं है कि Object से protected तरीकों एक अंतरफलक में एक default विधि में उपलब्ध नहीं हैं नहीं है।

Section 9.2 of the JLS कहता है:

एक अंतरफलक कोई सीधा superinterfaces है, तो इंटरफ़ेस परोक्ष एक public abstract सदस्य विधि m हस्ताक्षर s, वापसी प्रकार r साथ वाणी, और खंड t फेंकता प्रत्येक public उदाहरण विधि m करने के लिए इसी हस्ताक्षर s के साथ, वापसी प्रकार r, और Object में घोषित t को फेंक देता है, जब तक कि abstract विधि उसी हस्ताक्षर, समान वापसी प्रकार और एक compat के साथ नहीं ible throws क्लॉज स्पष्ट रूप से इंटरफ़ेस द्वारा घोषित किया गया है।

एक इंटरफेस Object से कुछ भी प्राप्त नहीं होगा, लेकिन यह परोक्ष सभी publicObject तरीकों घोषित करेंगे। इसमें protected विधियां शामिल नहीं हैं। यह बताता है कि clone और finalize क्यों नहीं कहा जा सकता है; उन्हें एक इंटरफेस में घोषित नहीं किया जाता है।

+0

दिलचस्प। मुझे पता नहीं था कि जब वे 'डिफ़ॉल्ट' विधि घोषित करते हैं तो इंटरफेस 'ऑब्जेक्ट' से प्राप्त नहीं होते हैं। हालांकि, आप सीधे 'डिफ़ॉल्ट' विधि को कॉल नहीं कर सकते हैं; इसे किसी ऑब्जेक्ट पर कॉल किया जाना चाहिए जिसका वर्ग सीधे या अप्रत्यक्ष रूप से इंटरफ़ेस लागू करता है। उस वर्ग में 'ऑब्जेक्ट' से कोई संदेह नहीं होगा। इस प्रकार, इसके लिए अनुमति देना सुरक्षित होना चाहिए। दिलचस्प डिजाइन निर्णय। –

+2

@RaffiKhatchadourian बस स्पष्ट करने के लिए, इंटरफेस ** कभी भी 'ऑब्जेक्ट' से प्राप्त नहीं होता है, भले ही कोई डिफ़ॉल्ट विधि हो या नहीं। वे बस नहीं करते हैं। 'ऑब्जेक्ट' से विरासत में समस्या यह है कि उदाहरण के लिए 'i' लागू करने वाली किसी भी कक्षा द्वारा 'toString()' विधि को ओवरराइड किया जा सकता है, तो कौन सा कार्यान्वयन चुना जाना चाहिए? इंटरफ़ेस या कक्षा में से एक जो विरासत को लागू करता है? – biziclop

+0

@biziclop अगर ऐसा होता है तो ** ** ऑब्जेक्ट 'से ** कभी भी उत्तराधिकारी नहीं होता है, तो' ऑब्जेक्ट ओ = i; 'कहां है, जहां मेरे पास एक इंटरफ़ेस कानूनी का संकलन-समय प्रकार है? असल में, यह http://stackoverflow.com/questions/6056124/do-interfaces-inherit-from-object-class-in-java से संबंधित प्रतीत होता है। –

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