Hej! Idag avslutar vi en serie lektioner om principerna för OOP. I den här lektionen kommer vi att prata om Java-polymorfism. Polymorfism är förmågan att arbeta med flera typer som om de vore samma typ. Dessutom kommer objektens beteende att vara olika beroende på deras typ. Låt oss ta en närmare titt på detta uttalande. Låt oss börja med den första delen: 'förmågan att arbeta med flera typer som om de vore samma typ'. Hur kan olika typer vara samma? Det låter lite konstigt :/ Faktum är att det hela är väldigt enkelt. Till exempel uppstår denna situation vid vanlig användning av arv. Låt oss se hur det fungerar. Anta att vi har en enkel Cat- förälderklass med en single run()- metod:
När denna 'generalisering' är oönskad och vi istället behöver att varje art beter sig annorlunda, gör varje typ sin egen grej. Tack vare polymorfism kan du skapa ett enda gränssnitt (uppsättning metoder) för ett brett utbud av klasser. Detta gör programmen mindre komplicerade. Även om vi utökar programmet till att stödja 40 typer av katter, skulle vi fortfarande ha det enklaste gränssnittet: en enda
run() -metod för alla 40 katter.
public class Cat {
public void run() {
System.out.println("Run!");
}
}
Nu ska vi skapa tre klasser som ärver Cat : Lion , Tiger och Cheetah .
public class Lion extends Cat {
@Override
public void run() {
System.out.println("Lion runs at 80 km/h");
}
}
public class Tiger extends Cat {
@Override
public void run() {
System.out.println("Tiger runs at 60 km/h");
}
}
public class Cheetah extends Cat {
@Override
public void run() {
System.out.println("Cheetah runs at up to 120 km/h");
}
}
Så vi har 3 klasser. Låt oss modellera situationen där vi kan arbeta med dem som om de vore samma klass. Föreställ dig att en av våra katter är sjuk och behöver hjälp av Dr Dolittle. Låt oss försöka skapa en Dolittle- klass som kan läka lejon, tigrar och geparder.
public class Dolittle {
public void healLion(Lion lion) {
System.out.println("Lion is healthy!");
}
public void healTiger(Tiger tiger) {
System.out.println("Tiger is healthy!");
}
public void healCheetah(Cheetah cheetah) {
System.out.println("Cheetah is healthy!");
}
}
Det verkar som om problemet är löst: klassen är skriven och redo att gå. Men vad gör vi om vi vill utöka vårt program? Vi har för närvarande bara 3 typer: lejon, tigrar och geparder. Men det finns mer än 40 typer av katter i världen. Föreställ dig vad som skulle hända om vi lade till separata klasser för manuler, jaguarer, Maine Coons, huskatter och allt annat. Själva programmet kommer naturligtvis att fungera, men vi måste hela tiden lägga till nya metoder till Dolittle -klassen för att läka varje typ av katt. Som ett resultat kommer det att växa till oöverträffade storlekar. Det är här polymorfism - "förmågan att arbeta med flera typer som om de vore samma typ" - kommer in. Vi behöver inte skapa otaliga metoder för att göra samma sak - läka en katt. En metod räcker för dem alla:
public class Dolittle {
public void healCat(Cat cat) {
System.out.println("The patient is healthy!");
}
}
Metoden healCat() kan acceptera Lion- , Tiger- och Cheetah -objekt – de är alla instanser av Cat :
public class Main {
public static void main(String[] args) {
Dolittle dolittle = new Dolittle();
Lion simba = new Lion();
Tiger shereKhan = new Tiger();
Cheetah chester = new Cheetah();
dolittle.healCat(simba);
dolittle.healCat(shereKhan);
dolittle.healCat(chester);
}
}
Konsolutgång: Patienten är frisk! Patienten är frisk! Patienten är frisk! Alltså vår Dolittleklass arbetar med olika typer som om de vore samma typ. Låt oss nu ta itu med den andra delen: "Dessutom kommer objektens beteende att vara olika beroende på deras typ". Det hela är väldigt enkelt. I naturen springer varje katt på ett annat sätt. Som ett minimum kör de i olika hastigheter. Bland våra tre kattdjur är geparden snabbast, medan tigern och lejonet springer långsammare. Med andra ord är deras beteende annorlunda. Polymorfism gör mer än att bara låta oss använda olika typer som en. Det låter oss också komma ihåg deras olikheter och bevara beteendet som är specifikt för var och en av dem. Följande exempel illustrerar detta. Anta att våra katter, efter ett lyckat tillfrisknande, bestämde sig för att njuta av en liten löprunda. Vi lägger till detta till vår Dolittle -klass:
public class Dolittle {
public void healCat(Cat cat) {
System.out.println("The patient is healthy!");
cat.run();
}
}
Låt oss försöka köra samma kod för att behandla tre djur:
public static void main(String[] args) {
Dolittle dolittle = new Dolittle();
Lion simba = new Lion();
Tiger shereKhan = new Tiger();
Cheetah chester = new Cheetah();
dolittle.healCat(simba);
dolittle.healCat(shereKhan);
dolittle.healCat(chester);
}
Och så här ser resultatet ut: Patienten är frisk! Lion springer i 80 km/h. Patienten är frisk! Tiger går i 60 km/h. Patienten är frisk! Geparden springer i upp till 120 km/h Här ser vi tydligt att föremåls specifika beteende bevaras, även om vi skickade alla tre djuren till metoden efter att ha 'generaliserat' dem till Cat . På grund av polymorfism minns Java väl att dessa inte bara är vilka tre katter som helst. De är ett lejon, en tiger och en gepard, som löper olika. Detta illustrerar polymorfismens främsta fördel: flexibilitet. När vi behöver implementera någon funktionalitet som delas av många typer, blir lejon, tigrar och geparder helt enkelt "katter". Alla djur är olika, men i vissa situationer är en katt en katt, oavsett art :) Här är lite videobekräftelse för dig.
Mer läsning: |
---|
GO TO FULL VERSION