Hei! Du bruker allerede Java-metoder og vet mye om dem. Hvordan metodeoverstyring fungerer - 1Du har sikkert kommet over en klasse med mange metoder som har samme navn, men forskjellige argumentlister. Du vil huske at vi i disse tilfellene brukte metodeoverbelastning. I dag skal vi se på en annen situasjon. Tenk deg at vi har én felles metode, men den skal gjøre forskjellige ting avhengig av hvilken klasse den kalles i. Hvordan implementerer vi denne atferden? For å forstå dette, la oss ta Animalforeldreklassen, som representerer dyr, og lage en speakmetode i den:

public class Animal {
  
   public void speak() {

       System.out.println("Hello!");
   }
}
Selv om vi nettopp har begynt å skrive programmet vårt, kan du sannsynligvis se et potensielt problem: verden er full av mange dyr, og de "snakker" alle forskjellig: katter mjauer, ender kvaksalver, slanger suser osv. Målet vårt er enkelt: Hvordan metodeoverstyring fungerer - 2vi ønsker å unngå å lage en haug med metoder for å snakke. I stedet for å lage en meow()metode for mjauing, hiss()for susing osv., ønsker vi at slangen skal suse, katten mjauer, og hunden skal bjeffe når metoden speak()kalles. Vi kan enkelt oppnå dette ved å bruke metodeoverstyring . Wikipedia forklarer begrepet som følger: Metodeoverstyring, i objektorientert programmering, er en språkfunksjon som lar en underklasse eller barneklasse gi en spesifikk implementering av en metode som allerede er levert av en av dens superklasser eller overordnede klasser. Det er i grunnen riktig. Overstyring lar deg ta en metode fra en overordnet klasse og skrive din egen implementering i hver avledet klasse. Den nye implementeringen i barneklassen «erstatter» den i forelderen. La oss se hvordan dette ser ut med et eksempel. La oss lage 4 etterkommere av Animalklassen vår:

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!");
   }
}
Her er et lite livhack for fremtiden: for å overstyre metodene til en overordnet klasse, gå inn i koden til den avledede klassen i IntelliJ IDE , trykk Ctrl+O og velg Overstyr metoder... fra menyen. Bli vant til å bruke hurtigtaster fra første stund. De vil øke hastigheten på kodingen! For å få ønsket oppførsel gjorde vi et par ting:
  1. I hver etterkommerklasse laget vi en metode med samme navn som metoden i overordnet klasse.
  2. Vi fortalte kompilatoren at vi ikke bare gir metoden samme navn som i overordnet klasse, men at vi heller ønsker å overstyre dens oppførsel. Denne "meldingen" til kompilatoren formidles via @Override- kommentaren.
    @Override-kommentaren over en metode forteller kompilatoren (så vel som andre programmerere som leser koden din), "Ikke bekymre deg. Dette er ikke en feil eller forglemmelse. Jeg er klar over at denne metoden allerede eksisterer, og jeg vil overstyre den .

  3. Vi skrev implementeringen vi trenger for hver etterkommerklasse. Når speak()metoden kalles, skal en slange hvese, en bjørn knurre, og så videre.
La oss se hvordan dette fungerer i et 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();
   }
}
Konsollutgang:

Woof! 
Meow! 
Growl! 
Hiss!
Flott, alt fungerer som det skal! Vi opprettet 4 referansevariabler hvis type er den Animaloverordnede klassen, og tildelte dem 4 forskjellige objekter av etterkommerklassene. Som et resultat oppfører hvert objekt seg annerledes. For hver av de avledede klassene speak()erstatter den overstyrte metoden den eksisterende speak()metoden for Animalklassen (som ganske enkelt viser "Snakker: " på konsollen). Hvordan metodeoverstyring fungerer - 3Metodeoverstyring har flere begrensninger:
  1. En overstyrt metode må ha de samme argumentene som metoden i den overordnede klassen.

    Hvis speakmetoden til den overordnede klassen tar a Stringsom input, må den overstyrte metoden i etterkommerklassen også ta a Stringsom input. Ellers vil kompilatoren generere en feil:

    
    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 overstyrte metoden må ha samme returtype som metoden i den overordnede klassen.

    Ellers får vi en kompileringsfeil:

    
    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 overstyrte metodens tilgangsmodifikator kan heller ikke avvike fra den opprinnelige:

    
    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 er metodeoverstyring en måte å implementere polymorfisme på. Det betyr at dens største fordel er den fleksibiliteten vi snakket om tidligere. Vi kan bygge et enkelt og logisk hierarki av klasser, hver med spesifikk oppførsel (bjeffende hunder, mjauende katter), men et enkelt grensesnitt - en enkelt speak()metode for alle i stedet for en haug med forskjellige metoder, f.eks bark(). meow(), osv.