Hej! Du använder redan Java-metoder och vet mycket om dem. Hur metodöverstyrning fungerar - 1Du har säkert stött på en klass med många metoder som har samma namn men olika argumentlistor. Du kommer ihåg att vi i dessa fall använde metodöverbelastning. Idag ska vi titta på en annan situation. Föreställ dig att vi har en gemensam metod, men den ska göra olika saker beroende på vilken klass den kallas i. Hur implementerar vi detta beteende? För att förstå detta, låt oss ta Animalföräldraklassen, som representerar djur, och skapa en speakmetod i den:

public class Animal {
  
   public void speak() {

       System.out.println("Hello!");
   }
}
Även om vi precis har börjat skriva vårt program, kan du förmodligen se ett potentiellt problem: världen är full av massor av djur, och de "talar" alla olika: katter jamar, ankor kvackar, ormar väser, etc. Vårt mål är enkelt: Hur metodöverstyrning fungerar - 2vi vill undvika att skapa en massa metoder för att tala. Istället för att skapa en meow()metod för att jama, hiss()för att väsa etc. vill vi att ormen ska väsa, katten jaja och hunden ska skälla när metoden speak()kallas. Vi kan enkelt uppnå detta genom att använda metodöverstyrning . Wikipedia förklarar termen på följande sätt: Metodöverskridande, i objektorienterad programmering, är en språkfunktion som tillåter en underklass eller underklass att tillhandahålla en specifik implementering av en metod som redan tillhandahålls av en av dess superklasser eller överordnade klasser. Det är i princip korrekt. Åsidosättande låter dig ta någon metod av en överordnad klass och skriva din egen implementering i varje härledd klass. Den nya implementeringen i barnklassen "ersätter" den i föräldern. Låt oss se hur det här ser ut med ett exempel. Låt oss skapa 4 ättlingar till vår Animalklass:

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!");
   }
}
Här är ett litet lifehack för framtiden: för att åsidosätta metoderna för en överordnad klass, gå in i koden för den härledda klassen i IntelliJ IDE , tryck på Ctrl+O och välj Åsidosätt metoder... från menyn. Vänj dig vid att använda snabbtangenter från början. De kommer att påskynda kodningen! För att få det önskade beteendet gjorde vi några saker:
  1. I varje descendant-klass skapade vi en metod med samma namn som metoden i den överordnade klassen.
  2. Vi sa till kompilatorn att vi inte bara ger metoden samma namn som i den överordnade klassen utan snarare vill vi åsidosätta dess beteende. Detta "meddelande" till kompilatorn förmedlas via @Override- kommentaren.
    @Override-kommentaren ovanför en metod säger till kompilatorn (liksom andra programmerare som läser din kod), "Oroa dig inte. Detta är inte ett misstag eller förbiseende. Jag är medveten om att den här metoden redan finns och jag vill åsidosätta den .

  3. Vi skrev implementeringen vi behöver för varje efterkommande klass. När speak()metoden kallas ska en orm fräsa, en björn morra och så vidare.
Låt oss se hur detta fungerar i ett 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();
   }
}
Konsolutgång:

Woof! 
Meow! 
Growl! 
Hiss!
Jättebra, allt fungerar som det ska! Vi skapade 4 referensvariabler vars typ är den Animalöverordnade klassen, och tilldelade dem 4 olika objekt i de efterkommande klasserna. Som ett resultat beter sig varje objekt annorlunda. speak()För var och en av de härledda klasserna ersätter den åsidosatta metoden den befintliga speak()metoden för Animalklassen (som helt enkelt visar "Speaking: " på konsolen). Hur metodöverstyrning fungerar - 3Åsidosättande av metod har flera begränsningar:
  1. En åsidosatt metod måste ha samma argument som metoden i den överordnade klassen.

    Om speakmetoden för den överordnade klassen tar a Stringsom indata, måste den åsidosatta metoden i den efterkommande klassen också ta a Stringsom indata. Annars kommer kompilatorn att generera ett fel:

    
    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. Den åsidosatta metoden måste ha samma returtyp som metoden i den överordnade klassen.

    Annars får vi ett kompileringsfel:

    
    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. Den åsidosatta metodens åtkomstmodifierare kan inte heller skilja sig från den ursprungliga:

    
    public class Animal {
    
       public void speak() {
    
           System.out.println("Hello!");
       }
    }
    
    public class Cat extends Animal {
    
       @Override
       private void speak() {      // Error!
           System.out.println("Meow!");
       }
    }
    
I Java är metodöverstyrning ett sätt att implementera polymorfism. Det betyder att dess främsta fördel är den flexibiliteten som vi pratade om tidigare. Vi kan bygga en enkel och logisk hierarki av klasser, var och en med specifikt beteende (skallande hundar, jamande katter) men ett enda gränssnitt - en enda speak()metod för alla snarare än en massa olika metoder, t.ex. , bark(), meow()etc.