दिलचस्प पोस्ट
जावा स्क्रिप्ट में नाम स्ट्रिंग के द्वारा गतिशील वैश्विक गति प्राप्त करें पूर्णांक आवरण वर्ग और == ऑपरेटर – जहां व्यवहार निर्दिष्ट है? एलएनके 4098 का ​​समाधान: डिफ़ॉल्ट लिब 'एमएसवीसीआरटी' के साथ संघर्ष C ++ वैश्विक प्रारंभिक आदेश निर्भरताओं पर ध्यान नहीं देता? मेमोरी में सुरक्षित रूप से मिटाना पासवर्ड (पायथन) जावा में एक "सरोगेट जोड़ी" क्या है? हर बार जब मैं मॉलोक का उपयोग करता हूं तो मुझे एक चेतावनी क्यों मिलती है? स्ट्रिंग कैपिटलाइज़ करें PHP फ़ंक्शन के साथ अपरिभाषित चर समस्या एचटीएमएल में दशमलव अंक संरेखित करें Codeigniter – मैं अपने एक नियंत्रक और एक मॉडल के लिए एक अलग डेटाबेस का उपयोग / कनेक्ट करने के लिए देख रहा हूं एएसपी.एनटी वेब एपीआई में त्रुटियों की वापसी के लिए सर्वश्रेष्ठ अभ्यास टिनकेटर का उपयोग करने वाला टाइमर कैसे बनाएं? HTML दस्तावेज़ की वर्ण एन्कोडिंग घोषित नहीं हुई थी डब्ल्यूआईटीएटी का उपयोग करके उस निर्देशिका में मनमाना फाइलों के साथ एक निर्देशिका प्राप्त करें

एक ही पद्धति के साथ एक वर्ग में दो इंटरफेस लागू करना। किस इंटरफ़ेस विधि को ओवरराइड किया गया है?

उसी पद्धति के नाम और हस्ताक्षर के साथ दो इंटरफेस। लेकिन एक एकल वर्ग द्वारा कार्यान्वित किया जाता है तो कैसे संकलक किस पद्धति की पहचान करेगा किस अंतरफलक के लिए है?

उदाहरण के लिए:

interface A{ int f(); } interface B{ int f(); } class Test implements A, B{ public static void main(String... args) throws Exception{ } @Override public int f() { // from which interface A or B return 0; } } 

वेब के समाधान से एकत्रित समाधान "एक ही पद्धति के साथ एक वर्ग में दो इंटरफेस लागू करना। किस इंटरफ़ेस विधि को ओवरराइड किया गया है?"

यदि एक प्रकार दो इंटरफेस लागू करता है, और प्रत्येक interface एक ऐसी विधि को परिभाषित करता है जिसमें एक समान हस्ताक्षर होता है, तो प्रभाव में केवल एक ही विधि होती है, और वे भिन्न नहीं होते हैं अगर, कहते हैं, दो विधियों में विवादित वापसी प्रकार हैं, तो यह एक संकलन त्रुटि होगी। यह विरासत का सामान्य नियम है, विधि अधिभावीकरण, छिपाना, और घोषणाएं, और केवल 2 से विरासत में मिली interface विधियों के बीच, बल्कि interface और एक सुपर class विधि या संभवतः जेनेरिक के प्रकार के विलोपन के कारण भी संघर्ष करने के लिए संभव संघर्ष पर लागू होता है ।


संगतता उदाहरण

यहां एक उदाहरण है जहां आपके पास interface Gift , जिसमें present() पद्धति (जैसे उपहार प्रस्तुत करना), और एक interface Guest भी है, जिसमें एक present() विधि भी है (जैसा कि अतिथि उपस्थित है और अनुपस्थित नहीं है )।

Presentable johnny एक Gift और Guest दोनों है

 public class InterfaceTest { interface Gift { void present(); } interface Guest { void present(); } interface Presentable extends Gift, Guest { } public static void main(String[] args) { Presentable johnny = new Presentable() { @Override public void present() { System.out.println("Heeeereee's Johnny!!!"); } }; johnny.present(); // "Heeeereee's Johnny!!!" ((Gift) johnny).present(); // "Heeeereee's Johnny!!!" ((Guest) johnny).present(); // "Heeeereee's Johnny!!!" Gift johnnyAsGift = (Gift) johnny; johnnyAsGift.present(); // "Heeeereee's Johnny!!!" Guest johnnyAsGuest = (Guest) johnny; johnnyAsGuest.present(); // "Heeeereee's Johnny!!!" } } 

ऊपर स्निपेट संकलन और रन

ध्यान दें कि केवल एक ही @Override आवश्यक है !!! । इसका कारण यह है कि Gift.present() और Guest.present() " Guest.present()Guest.present() " ( जेएलएस 8.4.2 ) हैं।

इस प्रकार, johnny केवल present() का एक कार्यान्वयन है, और इससे कोई फर्क नहीं पड़ता कि आप johnny कैसे व्यवहार करते हैं, चाहे Gift रूप में या Guest रूप में, इन्हें आमंत्रित करने के लिए केवल एक ही तरीका है


असंगति उदाहरण

यहां एक ऐसा उदाहरण दिया गया है जहां दो विरासत पद्धतियां नहीं हैं @Override ओवरराइड -समित:

 public class InterfaceTest { interface Gift { void present(); } interface Guest { boolean present(); } interface Presentable extends Gift, Guest { } // DOES NOT COMPILE!!! // "types InterfaceTest.Guest and InterfaceTest.Gift are incompatible; // both define present(), but with unrelated return types" } 

यह आगे दोहराता है कि सदस्यों को एक interface से विरासत में लाने के लिए सदस्य घोषणाओं के सामान्य नियम का पालन करना होगा। यहां हमारे पास Gift और Guest present() असंगत रिटर्न प्रकारों के साथ: एक अन्य boolean void कर देता है एक ही कारण के लिए कि आप एक void present() और एक boolean present() एक प्रकार में नहीं कर सकते, यह उदाहरण एक संकलन त्रुटि का कारण है।


सारांश

आप उन विधियों को प्राप्त कर सकते हैं, जो @ ओवरराइड -विभिन्न हैं, विधि अधिलेखित और छिपाने की सामान्य आवश्यकताओं के अधीन। चूंकि वे @Override ओवरराइड -विभिन्न हैं, प्रभावी रूप से लागू करने के लिए केवल एक ही तरीका है, और इस प्रकार इसमें अंतर करने / चयन करने के लिए कुछ भी नहीं है।

संकलक को यह पता करने की आवश्यकता नहीं है कि किस इंटरफ़ेस के लिए यह विधि है, क्योंकि एक बार वे @Override ओवरराइड -विभिन्न होने के लिए निर्धारित हो जाने पर, वे एक ही विधि हैं।

संभावित असंगतिओं का हल करना एक मुश्किल काम हो सकता है, लेकिन यह एक और मुद्दा है।

संदर्भ

  • जेएलएस 8.4.2 विधि हस्ताक्षर
  • जेएलएस 8.4.8 वंशानुक्रम, ओवरराइडिंग, और छुपा
  • जेएलएस 8.4.8.3 ओवरराइडिंग और छुपा में आवश्यकताएँ
  • जेएलएस 8.4.8.4 ओवरराइड-समतुल्य हस्ताक्षर के साथ तरीकों का आवंटन
    • "यह क्लास के लिए ओवरराइड-समकक्ष हस्ताक्षर वाले कई तरीकों को प्राप्त करना संभव है।"

जहां तक ​​कंपाइलर का संबंध है, उन दोनों विधियां समान हैं। दोनों के एक कार्यान्वयन होगा।

यह एक समस्या नहीं है, यदि दो विधियों को प्रभावी रूप से एक समान है, इसमें उन्हें एक ही कार्यान्वयन होना चाहिए। यदि वे संविदात्मक रूप से अलग हैं (प्रत्येक इंटरफ़ेस के लिए प्रलेखन के अनुसार), तो आपको परेशानी होगी।

इस प्रश्न के लिए डुप्लिकेट के रूप में चिह्नित किया गया था https://stackoverflow.com/questions/24401064/understanding-and-solving-the-diamond-problems-in-java

एक बहु विरासत समस्या पाने के लिए आपको जावा 8 की आवश्यकता है, लेकिन यह अभी भी एक डायर समस्या नहीं है जैसे कि।

 interface A { default void hi() { System.out.println("A"); } } interface B { default void hi() { System.out.println("B"); } } class AB implements A, B { // won't compile } new AB().hi(); // won't compile. 

जैसा कि जेबी निजेट ने कहा है कि आप यह मेरे ओवरराइडिंग को ठीक कर सकते हैं।

 class AB implements A, B { public void hi() { A.super.hi(); } } 

हालांकि, आपके पास समस्या नहीं है

 interface D extends A { } interface E extends A { } interface F extends A { default void hi() { System.out.println("F"); } } class DE implement D, E { } new DE().hi(); // prints A class DEF implement D, E, F { } new DEF().hi(); // prints F as it is closer in the heirarchy than A. 

पहचानने के लिए कुछ भी नहीं है इंटरफेस केवल एक विधि नाम और हस्ताक्षर पर भरोसा करते हैं। यदि दोनों इंटरफेसेस में एक ही नाम और हस्ताक्षर की विधि होती है, तो कार्यान्वयन वर्ग एकल कंक्रीट विधि के साथ दोनों इंटरफेस विधियों को लागू कर सकता है।

हालांकि, अगर दो इंटरफ़ेस विधि के सिमेंटिक अनुबंध विपरीत हैं, तो आप बहुत ज्यादा खो चुके हैं; आप एक ही कक्षा में दोनों इंटरफेस लागू नहीं कर सकते हैं।

इंटरफ़ेस को गुमनाम के रूप में लागू करने की कोशिश करें

 public class MyClass extends MySuperClass implements MyInterface{ MyInterface myInterface = new MyInterface(){ /* Overrided method from interface */ @override public void method1(){ } }; /* Overrided method from superclass*/ @override public void method1(){ } } 

इंटरफ़ेस के रूप में, हम केवल तरीकों को घोषित कर रहे हैं, कंक्रीट वर्ग जो इन दोनों इंटरफेस को समझता है, वह यह है कि केवल एक ही तरीका है (जैसा कि आपने बताया है कि जैसा कि आप दोनों का नाम बदला है)। इसलिए इसके साथ कोई मुद्दा नहीं होना चाहिए। आप ठोस पद्धति में उस विधि को परिभाषित करने में सक्षम होंगे।

लेकिन जब दो इंटरफ़ेस में एक ही नाम के साथ एक विधि होती है, लेकिन भिन्न रिटर्न प्रकार होता है और आप कंक्रीट क्लास में दो तरीकों को लागू करते हैं:

कृपया नीचे कोड देखें:

 public interface InterfaceA { public void print(); } public interface InterfaceB { public int print(); } public class ClassAB implements InterfaceA, InterfaceB { public void print() { System.out.println("Inside InterfaceA"); } public int print() { System.out.println("Inside InterfaceB"); return 5; } } 

जब संकलक विधि "सार्वजनिक शून्य प्रिंट ()" विधि को पहली बार इंटरफ़ेस में दिखता है और इसे हो जाता है। लेकिन फिर भी यह संकलन समय त्रुटि देता है कि वापसी प्रकार इंटरफ़ेसबी की विधि के साथ संगत नहीं है

तो यह कंपाइलर के लिए खराब हो जाता है

इस तरीके से, आप दो इंटरफ़ेस को लागू नहीं कर पाएंगे, जिनके पास एक ही नाम की विधि होती है, लेकिन भिन्न रिटर्न का प्रकार होता है।

ठीक है, यदि वे दोनों समान हैं तो इससे कोई फर्क नहीं पड़ता। यह उन दोनों को एक एकल ठोस पद्धति प्रति इंटरफेस विधि के साथ लागू करता है।