CodeGym /Blog Java /Poland /Polimorfizm w Javie
Autor
Milan Vucic
Programming Tutor at Codementor.io

Polimorfizm w Javie

Opublikowano w grupie Poland
Cześć! Dziś kończymy cykl lekcji na temat zasad programowania obiektowego (OOP). W tej lekcji porozmawiamy o polimorfizmie w Javie. Polimorfizm daje możliwość pracy z wieloma typami tak, jakby były one tym samym typem. Co więcej, zachowanie każdego obiektu będzie różne w zależności od jego typu. Przyjrzyjmy się bliżej temu stwierdzeniu. Polimorfizm w Javie - 1Zacznijmy od pierwszej części: 'daje możliwość pracy z wieloma typami tak, jakby były one tym samym typem'. Jak różne typy mogą być takie same? Trochę dziwnie to brzmi :/ Tak naprawdę, to wszystko jest bardzo proste. Na przykład taka sytuacja występuje podczas zwykłego korzystania z dziedziczenia. Zobaczmy, jak to działa. Załóżmy, że mamy prostą klasę nadrzędną Cat z jedną metodą run():

public class Cat {

   public void run() {
       System.out.println("Run!");
   }
}
Teraz utworzymy trzy klasy dziedziczące po klasie Cat: Lion, Tiger i 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");
   }
}
Zatem mamy 3 klasy. Zamodelujmy sytuację, w której możemy z nimi pracować tak, jakby były jedną klasą. Wyobraź sobie, że jeden z naszych kotów jest chory i potrzebuje pomocy doktora Dolittle. Spróbujmy stworzyć klasę Dolittle, która może leczyć lwy, tygrysy i gepardy.

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!");
   }
}
Wygląda na to, że problem został rozwiązany: klasa jest napisana i gotowa do pracy. Ale co zrobimy, jeśli będziemy chcieli rozszerzyć nasz program? Obecnie mamy tylko 3 typy: lwy, tygrysy i gepardy. Ale na świecie jest ponad 40 rodzajów kotów. Wyobraź sobie, co by się stało, gdybyśmy dodali osobne klasy dla manuli, jaguarów, kotów rasy Maine Coon, kotów domowych i całej reszty. Sam program będzie oczywiście działał, ale musimy stale dodawać nowe metody do klasy Dolittle, aby leczyć każdy typ kota. W rezultacie rozrośnie się do niespotykanych rozmiarów. W tym miejscu pojawia się polimorfizm i — "daje możliwość pracy z wieloma typami tak, jakby były one tym samym typem". Nie musimy tworzyć niezliczonych metod, aby zrobić to samo — wyleczyć kota. Dla wszystkich wystarczy jedna metoda:

public class Dolittle {

   public void healCat(Cat cat) {

       System.out.println("The patient is healthy!");
   }
}
Metoda healCat() może przyjmować obiekty Lion, Tiger i Cheetah — wszystkie są instancjami klasy 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);
   }
}
Wyświetlone zostanie:
Pacjent jest zdrowy! Pacjent jest zdrowy! Pacjent jest zdrowy!
Zatem nasza klasa Dolittle działa z różnymi typami tak, jakby były one tym samym typem. Zajmijmy się teraz drugą częścią: "zachowanie każdego obiektu będzie różne w zależności od jego typu". To wszystko jest bardzo proste. W naturze każdy kot biega inaczej. Co najmniej, poruszają się z różnymi prędkościami. Spośród naszych trzech kotowatych najszybszy jest gepard, a tygrys i lew biegają wolniej. Innymi słowy, ich zachowanie jest inne. Polimorfizm nie tylko pozwala nam używać różnych typów jak jednego. Pozwala też pamiętać o różnicach między nimi, zachowując charakterystyczne dla każdego z nich działanie. Ilustruje to poniższy przykład. Załóżmy, że nasze koty po udanej rekonwalescencji postanowiły trochę pobiegać. Dodamy to do naszej klasy Dolittle:

public class Dolittle {

   public void healCat(Cat cat) {

       System.out.println("The patient is healthy!");
       cat.run();
   }
}
Spróbujmy uruchomić ten sam kod, aby wyleczyć trzy zwierzęta:

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);
}
A oto jak wyglądają wyniki:
Pacjent jest zdrowy! Lew biega z prędkością 80 km/h Pacjent jest zdrowy! Tygrys biega z prędkością 60 km/h Pacjent jest zdrowy! Gepard biega z prędkością do 120 km/h
Wyraźnie widać, że działanie specyficzne dla obiektu zostało zachowane, mimo że wszystkie trzy zwierzęta przekazaliśmy metodzie po 'uogólnieniu' ich do klasy Cat. Dzięki polimorfizmowi Java dobrze pamięta, że to nie są po prostu trzy koty. Są to lew, tygrys i gepard, z których każdy biega inaczej. Polimorfizm w Javie - 2Ilustruje to główną zaletę polimorfizmu: elastyczność. Kiedy musimy zaimplementować jakąś funkcjonalność wspólną dla wielu typów, lwy, tygrysy i gepardy po prostu stają się 'kotami'. Wszystkie zwierzęta są różne, ale w niektórych sytuacjach kot to kot, niezależnie od gatunku :) Oto film z potwierdzeniem. Kiedy to 'uogólnienie' jest niepożądane i zamiast tego potrzebujemy, aby każdy gatunek zachowywał się inaczej, każdy typ robi swoje. Dzięki polimorfizmowi możesz stworzyć jeden interfejs (zestaw metod) dla wielu klas. Dzięki temu programy są mniej skomplikowane. Nawet gdybyśmy rozszerzyli program tak, aby obsługiwał 40 typów kotów, nadal mielibyśmy najprostszy interfejs: jedną metodę run() dla wszystkich 40 kotów.
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION