Computer >> कंप्यूटर >  >> प्रोग्रामिंग >> Java

जावा में डिफ़ॉल्ट विधियों का उपयोग करके हीरे की समस्या को कैसे हल करें?

विरासत दो वर्गों के बीच एक संबंध है जहां एक वर्ग दूसरे वर्ग के गुणों को प्राप्त करता है। इस संबंध को -

. के रूप में विस्तृत कीवर्ड का उपयोग करके परिभाषित किया जा सकता है
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

  1. जावा में डिफ़ॉल्ट विधियों का उपयोग करके हीरे की समस्या को कैसे हल करें

    विरासत दो वर्गों के बीच एक संबंध है जहां एक वर्ग दूसरे वर्ग के गुणों को प्राप्त करता है। इस संबंध को - . के रूप में विस्तृत कीवर्ड का उपयोग करके परिभाषित किया जा सकता है public class A extends B{} जिस वर्ग को गुण विरासत में मिलते हैं उसे उप वर्ग या बाल वर्ग के रूप में जाना जाता है और जिस वर्ग की स

  1. जावा में फ़ाइल उपयोगिता विधियों का उपयोग करके निर्देशिका कैसे बनाएं?

    जावा 7 के बाद से File.02s वर्ग को पेश किया गया था इसमें (स्थिर) विधियां शामिल हैं जो फाइलों, निर्देशिकाओं या अन्य प्रकार की फाइलों पर काम करती हैं। createDirectory() फ़ाइलें . की विधि वर्ग आवश्यक निर्देशिका का पथ स्वीकार करता है और एक नई निर्देशिका बनाता है। उदाहरण निम्नलिखित जावा उदाहरण उपयोगक

  1. जावा 9 में JShell के डिफ़ॉल्ट संपादक को कैसे संशोधित करें?

    जेशेल लागू करता है REPL (पढ़ें-मूल्यांकन-प्रिंट लूप) जो कमांड-लाइन से कोड पढ़ता है , दिए गए स्निपेट का मूल्यांकन करता है, और परिणाम को वापस हमारे पास प्रिंट करता है। JShell में, JShell Editor Pad का उपयोग करके डिफ़ॉल्ट JShell संपादक से कोड संपादित करना संभव है . हम /सेट . का भी उपयोग कर सकते हैं