Bună! Folosești deja metode Java și știi multe despre ele. Cum funcționează suprascrierea metodei - 1Cu siguranță ați dat peste o clasă cu multe metode care au același nume, dar liste de argumente diferite. Vă veți aminti că în acele cazuri am folosit supraîncărcarea metodei. Astăzi vom arunca o privire asupra unei situații diferite. Imaginați-vă că avem o metodă comună, dar ar trebui să facă lucruri diferite în funcție de clasa în care este chemată. Cum implementăm acest comportament? Pentru a înțelege acest lucru, să luăm Animalclasa părinte, care reprezintă animale, și să creăm o speakmetodă în ea:

public class Animal {
  
   public void speak() {

       System.out.println("Hello!");
   }
}
Deși tocmai am început să ne scriem programul, probabil că puteți vedea o potențială problemă: lumea este plină de o mulțime de animale și toate „vorbesc” diferit: pisicile miaună, rațe șuieră, șerpii șuierat etc. Scopul nostru este simplu: Cum funcționează suprascrierea metodei - 2noi doresc să evite crearea unei grămadă de metode de vorbire. În loc să creăm o meow()metodă de mieunat, hiss()de șuierat etc., vrem ca șarpele să șuiera, pisica să miaună și câinele să latre atunci când speak()este apelată metoda. Putem realiza cu ușurință acest lucru folosind suprascrierea metodei . Wikipedia explică termenul după cum urmează: Suprascrierea metodei, în programarea orientată pe obiecte, este o caracteristică a limbajului care permite unei subclase sau clase copil să ofere o implementare specifică a unei metode care este deja furnizată de una dintre superclasele sau clasele părinte ale acesteia. Asta e practic corect. Suprascrierea vă permite să luați o metodă a unei clase părinte și să scrieți propria implementare în fiecare clasă derivată. Noua implementare din clasa copil o „inlocuieste” pe cea din parinte. Să vedem cum arată asta cu un exemplu. Să creăm 4 descendenți ai Animalclasei noastre:

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!");
   }
}
Iată un mic truc de viață pentru viitor: pentru a suprascrie metodele unei clase părinte, accesați codul clasei derivate din IntelliJ IDE , apăsați Ctrl+O și selectați Override methods... din meniu. Obișnuiește-te să folosești tastele rapide de la început. Vor accelera codarea! Pentru a obține comportamentul dorit, am făcut câteva lucruri:
  1. În fiecare clasă descendentă, am creat o metodă cu același nume ca metoda din clasa părinte.
  2. Am spus compilatorului că nu doar dăm metodei același nume ca în clasa părinte, ci mai degrabă vrem să-i suprascriem comportamentul. Acest „mesaj” către compilator este transmis prin adnotarea @Override .
    Adnotarea @Override de deasupra unei metode îi spune compilatorului (precum și altor programatori care vă citesc codul) „Nu vă faceți griji. Aceasta nu este o greșeală sau o neglijență. Sunt conștient că această metodă există deja și vreau să o înlocuiesc. .

  3. Am scris implementarea de care avem nevoie pentru fiecare clasă descendentă. Când speak()este numită metoda, un șarpe ar trebui să șuiera, un urs ar trebui să mârâie și așa mai departe.
Să vedem cum funcționează asta într-un program:

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();
   }
}
Ieșire consolă:

Woof! 
Meow! 
Growl! 
Hiss!
Super, totul funcționează așa cum trebuie! Am creat 4 variabile de referință al căror tip este Animalclasa părinte și le-am atribuit 4 obiecte diferite ale claselor descendente. Ca urmare, fiecare obiect se comportă diferit. Pentru fiecare dintre clasele derivate, speak()metoda suprascrisă înlocuiește metoda existentă speak()a Animalclasei (care afișează pur și simplu „Speaking:” pe consolă). Cum funcționează suprascrierea metodei - 3Suprascrierea metodei are mai multe limitări:
  1. O metodă suprascrisă trebuie să aibă aceleași argumente ca metoda din clasa părinte.

    Dacă speakmetoda clasei părinte ia a Stringca intrare, atunci metoda suprascrisă din clasa descendentă trebuie să ia și a Stringca intrare. În caz contrar, compilatorul va genera o eroare:

    
    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. Metoda suprascrisă trebuie să aibă același tip de returnare ca și metoda din clasa părinte.

    În caz contrar, vom primi o eroare de compilare:

    
    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. Modificatorul de acces al metodei suprascrise, de asemenea, nu poate diferi de cel inițial:

    
    public class Animal {
    
       public void speak() {
    
           System.out.println("Hello!");
       }
    }
    
    public class Cat extends Animal {
    
       @Override
       private void speak() {      // Error!
           System.out.println("Meow!");
       }
    }
    
În Java, suprascrierea metodei este o modalitate de a implementa polimorfismul. Asta înseamnă că principalul său avantaj este acea flexibilitate despre care am vorbit mai devreme. Putem construi o ierarhie simplă și logică de clase, fiecare cu un comportament specific (câini care lătră, pisici mieunate), dar o singură interfață - o singură speak()metodă pentru toată lumea, mai degrabă decât o grămadă de metode diferite, de exemplu bark(), meow()etc.