विरासत दो वर्गों के बीच एक संबंध है जहां एक वर्ग दूसरे वर्ग के गुणों को प्राप्त करता है। इस संबंध को -
. के रूप में विस्तृत कीवर्ड का उपयोग करके परिभाषित किया जा सकता हैpublic class A extends B{ }
जिस वर्ग को गुण विरासत में मिलते हैं उसे उप वर्ग या बाल वर्ग के रूप में जाना जाता है और जिस वर्ग की संपत्ति विरासत में मिली है वह सुपर क्लास या मूल वर्ग है।
इनहेरिटेंस में सब क्लास ऑब्जेक्ट में सुपर क्लास के सदस्यों की एक कॉपी बनाई जाती है। इसलिए, उप-वर्ग ऑब्जेक्ट का उपयोग करके आप दोनों वर्गों के सदस्यों तक पहुंच सकते हैं।
एकाधिक विरासत में:
विभिन्न प्रकार के वंशानुक्रम उपलब्ध हैं, अर्थात् एकल, बहुस्तरीय, पदानुक्रमित, एकाधिक और संकर।
एकाधिक वंशानुक्रम में एक वर्ग को कई वर्गों के गुण विरासत में मिलते हैं। दूसरे शब्दों में, मल्टीपल इनहेरिटेंस में हमारे पास एक चाइल्ड क्लास और n नंबर पैरेंट क्लास हो सकते हैं। जावा एकाधिक वंशानुक्रम (कक्षाओं के साथ) का समर्थन नहीं करता है।
हीरे की समस्या
उदाहरण के लिए, मान लें कि जावा एकाधिक वंशानुक्रम का समर्थन करता है। उस धारणा के साथ निम्नलिखित उदाहरण पर विचार करें।
उदाहरण
यहां, हमारे पास नमूना . नामक एक अमूर्त वर्ग है सार विधि के साथ -
public class abstract Sample { public abstract demo(); }
फिर उसी पैकेज/फ़ोल्डर में, हमारे पास दो वर्ग हैं जो इस वर्ग का विस्तार कर रहे हैं और इसकी सार पद्धति को लागू करने का प्रयास कर रहे हैं, demo()।
public class Super1 extends Sample{ public void demo() { System.out.println("demo method of super1"); } } public class Super2 extends Sample{ public void demo() { System.out.println("demo method of super2"); } }
हमारी धारणा के अनुसार, चूंकि जावा एकाधिक वंशानुक्रम का समर्थन करता है, हम सुपर1 और सुपर2 दोनों वर्गों को इनहेरिट करने का प्रयास कर रहे हैं।
public class SubClass extends Super1, Super2 { public static void main(String args[]) { SubClass obj = new SubClass(); obj.demo(); } }
फिर, वंशानुक्रम के मूल नियम के अनुसार, उपवर्ग वस्तु में दोनों डेमो () विधियों की एक प्रति बनाई जानी चाहिए जो उपवर्ग को एक ही प्रोटोटाइप (नाम और तर्क) के साथ दो विधियों के साथ छोड़ देती है। फिर, यदि आप सबक्लास कंपाइलर के ऑब्जेक्ट का उपयोग करके डेमो() विधि को कॉल करते हैं तो एक अस्पष्ट स्थिति का सामना करना पड़ता है, न जाने किस विधि को कॉल करना है। जावा में इस समस्या को हीरे की समस्या के रूप में जाना जाता है।
इसके कारण जावा एकाधिक वंशानुक्रम का समर्थन नहीं करता है अर्थात, आप एक से अधिक अन्य वर्गों का विस्तार नहीं कर सकते हैं। फिर भी, यदि आप ऐसा करने का प्रयास करते हैं, तो एक संकलन समय त्रुटि उत्पन्न होती है।
संकलन समय त्रुटि
संकलन करने पर, उपरोक्त प्रोग्राम निम्न त्रुटि उत्पन्न करता है -
MultipleInheritanceExample.java:9: error: '{' expected public class MultipleInheritanceExample extends MyInterface1, MyInterface2{ ^ 1 errorको बढ़ाता है
समाधान
आप डिफ़ॉल्ट विधियों (Java8) और इंटरफेस का उपयोग करके जावा में एकाधिक वंशानुक्रम प्राप्त कर सकते हैं।
Java8 से वार्डों में डिफ़ॉल्ट तरीके एक इंटरफेस में पेश किया जाता है। अन्य अमूर्त विधियों के विपरीत, ये डिफ़ॉल्ट कार्यान्वयन वाले इंटरफ़ेस के तरीके हैं। यदि आपके पास इंटरफ़ेस में डिफ़ॉल्ट विधि है, तो इसे उन कक्षाओं में ओवरराइड करना (बॉडी प्रदान करना) अनिवार्य नहीं है जो पहले से ही इस इंटरफ़ेस को लागू कर रहे हैं।
आपके पास दो अलग-अलग इंटरफेस में एक ही डिफ़ॉल्ट तरीके (एक ही नाम और हस्ताक्षर) हो सकते हैं और एक वर्ग से आप इन दो इंटरफेस को लागू कर सकते हैं।
यदि आप ऐसा करते हैं, तो आपको डिफ़ॉल्ट विधि को उसके इंटरफ़ेस नाम के साथ स्पष्ट रूप से निर्दिष्ट करने वाले वर्ग से डिफ़ॉल्ट विधि को ओवरराइड करना होगा।
उदाहरण
interface MyInterface1{ public static int num = 100; public default void display() { System.out.println("display method of MyInterface1"); } } interface MyInterface2{ public static int num = 1000; public default void display() { System.out.println("display method of MyInterface2"); } } public class InterfaceExample implements MyInterface1, MyInterface2{ public void display() { MyInterface1.super.display(); //or, MyInterface2.super.display(); } public static void main(String args[]) { InterfaceExample obj = new InterfaceExample(); obj.display(); } }
आउटपुट
display method of MyInterface1 display method of MyInterface2