नमस्ते! आप पहले से ही Java विधियों का उपयोग करते हैं और उनके बारे में बहुत कुछ जानते हैं। मेथड ओवरराइडिंग कैसे काम करती है - 1निश्चित रूप से आप एक वर्ग में कई विधियों के साथ आए हैं जिनके नाम समान हैं लेकिन विभिन्न तर्क सूचियाँ हैं। आपको याद होगा कि उन मामलों में हमने मेथड ओवरलोडिंग का इस्तेमाल किया था। आज हम एक अलग स्थिति पर नजर डालेंगे। कल्पना कीजिए कि हमारे पास एक सामान्य तरीका है, लेकिन इसे किस वर्ग में बुलाया जाता है, इसके आधार पर इसे अलग-अलग काम करना चाहिए। हम इस व्यवहार को कैसे लागू करते हैं? इसे समझने के लिए, आइए Animalमूल वर्ग लें, जो जानवरों का प्रतिनिधित्व करता है, और speakइसमें एक विधि बनाएँ:
public class Animal {

   public void speak() {

       System.out.println("Hello!");
   }
}
हालांकि हमने अपना प्रोग्राम अभी लिखना शुरू ही किया है, आप शायद एक संभावित समस्या देख सकते हैं: दुनिया बहुत सारे जानवरों से भरी है, और वे सभी अलग-अलग तरीके से "बोलते" हैं: बिल्लियाँ म्याऊ, बत्तखें, सांपों की फुफकार आदि। हमारा लक्ष्य सरल है: मेथड ओवरराइडिंग कैसे काम करती है - 2हम बोलने के तरीकों का एक गुच्छा बनाने से बचना चाहते हैं। meow()म्याऊ करने, फुफकारने आदि के लिए एक विधि बनाने के बजाय hiss(), हम चाहते हैं कि सांप फुफकारे, बिल्ली म्याऊ करे, और कुत्ता भौंके जब speak()विधि को कहा जाए। हम ओवरराइडिंग विधि का उपयोग करके इसे आसानी से प्राप्त कर सकते हैं । विकिपीडिया इस शब्द की व्याख्या इस प्रकार करता है: मेथड ओवरराइडिंग, ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग में, एक भाषा सुविधा है जो एक उपवर्ग या चाइल्ड क्लास को एक विधि का विशिष्ट कार्यान्वयन प्रदान करने की अनुमति देती है जो पहले से ही इसके सुपरक्लास या पैरेंट क्लास में से एक द्वारा प्रदान की जाती है। यह मूल रूप से सही है। ओवरराइडिंग से आप पैरेंट क्लास की कोई विधि ले सकते हैं और प्रत्येक डिराइव्ड क्लास में अपना कार्यान्वयन लिख सकते हैं। बाल वर्ग में नया कार्यान्वयन माता-पिता में से एक को "प्रतिस्थापित" करता है। आइए देखें कि यह एक उदाहरण के साथ कैसा दिखता है। आइए अपनी Animalकक्षा के 4 वंशज बनाएँ:
public class Bear extends Animal {
   @Override
   public void speak() {
       System.out.println("Growl!");
   }
}
public class Cat extends Animal {

   @Override
   public void speak() {
       System.out.println("Meow!");
   }
}

public class Dog extends Animal {

   @Override
   public void speak() {
       System.out.println("Woof!");
   }
}


public class Snake extends Animal {

   @Override
   public void speak() {
       System.out.println("Hiss!");
   }
}
यहां भविष्य के लिए एक छोटा लाइफहैक है: मूल वर्ग के तरीकों को ओवरराइड करने के लिए, IntelliJ IDE में व्युत्पन्न वर्ग के कोड में जाएं , Ctrl+O दबाएं , और मेनू से ओवरराइड विधियों का चयन करें। शुरू से ही हॉटकीज़ का उपयोग करने की आदत डालें। वे कोडिंग को गति देंगे! वांछित व्यवहार प्राप्त करने के लिए, हमने कुछ चीज़ें कीं:
  1. प्रत्येक वंशज वर्ग में, हमने मूल वर्ग में विधि के समान नाम वाली एक विधि बनाई।
  2. हमने कंपाइलर को बताया कि हम केवल विधि को मूल वर्ग के समान नाम नहीं दे रहे हैं, बल्कि हम उसके व्यवहार को ओवरराइड करना चाहते हैं। कंपाइलर को यह "संदेश" @Override एनोटेशन के माध्यम से व्यक्त किया जाता है।
    एक विधि के ऊपर @Override एनोटेशन संकलक (साथ ही साथ आपके कोड को पढ़ने वाले अन्य प्रोग्रामर) को बताता है, "चिंता न करें। यह कोई गलती या निरीक्षण नहीं है। मुझे पता है कि यह विधि पहले से मौजूद है, और मैं इसे ओवरराइड करना चाहता हूं .

  3. हमने प्रत्येक वंश वर्ग के लिए आवश्यक कार्यान्वयन लिखा। जब speak()विधि का आह्वान किया जाता है, तो सांप को फुफकारना चाहिए, भालू को गरजना चाहिए, और इसी तरह।
आइए देखें कि यह प्रोग्राम में कैसे काम करता है:
public class Main {

   public static void main(String[] args) {

       Animal animal1 = new Dog();
       Animal animal2 = new Cat();
       Animal animal3 = new Bear();
       Animal animal4 = new Snake();

       animal1.speak();
       animal2.speak();
       animal3.speak();
       animal4.speak();
   }
}
कंसोल आउटपुट:

Woof! 
Meow! 
Growl! 
Hiss!
महान, सब कुछ वैसा ही काम करता है जैसा उसे करना चाहिए! हमने 4 संदर्भ चर बनाए जिनका प्रकार Animalमूल वर्ग है, और उन्हें वंशज वर्गों की 4 अलग-अलग वस्तुओं को सौंपा। नतीजतन, प्रत्येक वस्तु अलग तरह से व्यवहार करती है। व्युत्पन्न कक्षाओं में से प्रत्येक के लिए, ओवरराइड विधि वर्ग की speak()मौजूदा विधि को प्रतिस्थापित करती है (जो कंसोल पर "स्पीकिंग:" प्रदर्शित करती है)। ओवरराइडिंग विधि की कई सीमाएँ हैं: speak()Animalमेथड ओवरराइडिंग कैसे काम करती है - 3
  1. एक ओवरराइड विधि में मूल वर्ग में विधि के समान तर्क होने चाहिए।

    यदि speakमूल वर्ग की विधि Stringइनपुट के रूप में लेती है, तो अवरोही वर्ग में ओवरराइड विधि को भी Stringइनपुट के रूप में लेना चाहिए। अन्यथा, संकलक एक त्रुटि उत्पन्न करेगा:

    public class Animal {
    
       public void speak(String s) {
    
           System.out.println("Speaking: " + s);
       }
    }
    
    public class Cat extends Animal {
    
       @Override // Error!
       public void speak() {
           System.out.println("Meow!");
       }
    }

  2. ओवरराइड विधि में मूल वर्ग में विधि के समान वापसी प्रकार होना चाहिए।

    अन्यथा, हमें एक संकलन त्रुटि मिलेगी:

    public class Animal {
    
       public void speak() {
    
           System.out.println("Hello!");
       }
    }
    
    
    public class Cat extends Animal {
    
       @Override
       public String speak() {         // Error!
           System.out.println("Meow!");
           return "Meow!";
       }
    }

  3. ओवरराइड विधि का एक्सेस संशोधक भी मूल से भिन्न नहीं हो सकता है:

    public class Animal {
    
       public void speak() {
    
           System.out.println("Hello!");
       }
    }
    
    public class Cat extends Animal {
    
       @Override
       private void speak() {      // Error!
           System.out.println("Meow!");
       }
    }
जावा में, ओवरराइडिंग विधि बहुरूपता को लागू करने का एक तरीका है। इसका मतलब है कि इसका मुख्य लाभ वह लचीलापन है जिसके बारे में हमने पहले बात की थी। हम कक्षाओं का एक सरल और तार्किक पदानुक्रम बना सकते हैं, प्रत्येक विशिष्ट व्यवहार के साथ (भौंकने वाले कुत्ते, म्याऊं बिल्लियां) लेकिन एक इंटरफ़ेस - speak()विभिन्न तरीकों के समूह के बजाय सभी के लिए एक ही विधि, जैसे bark(), meow()आदि ।