JavaRush /Java блог /Random UA /Практика використання поліморфізму

Практика використання поліморфізму

Стаття з групи Random UA
Вітання! Сьогодні ми закінчуємо серію лекцій про принципи ОВП . На цьому занятті поговоримо про поліморфізм. Практика використання поліморфізму - 1Поліморфізм - це можливість працювати з кількома типами так, ніби це один і той самий тип. У цьому поведінка об'єктів буде різним залежно від цього, якого типу вони належать. Давай розглянемо це твердження докладніше. Почнемо з першої частини: «можливість працювати з кількома типами так, ніби це один і той самий тип». Як різні типи можуть бути при цьому одним і тим же? Звучить трохи дивно: Насправді все просто. Наприклад, така ситуація виникає при звичайному використанні наслідування. Подивимося, як це працює. Припустимо, у нас є простий батьківський клас Catіз єдиним методом run()— «бігти»:
public class Cat {

   public void run() {
       System.out.println("Бег!");
   }
}
А тепер створимо три класи, які успадковуються від Cat: Lion, Tigerі Cheetah, що позначають лева, тигра та гепарду.
public class Lion extends Cat {

   @Override
   public void run() {
       System.out.println("Лев бежит со швидкістью 80 км/ч");
   }
}

public class Tiger extends Cat {

   @Override
   public void run() {
       System.out.println("Тигр бежит со швидкістью 60 км/ч");
   }
}

public class Cheetah extends Cat {

   @Override
   public void run() {
       System.out.println("Гепард бежит со швидкістью до 120 км/ч");
   }
}
Отже, у нас є 3 класи. Давай змоделюємо ситуацію, за якої ми зможемо працювати з ними так, ніби це один і той самий клас. Припустимо, що хтось із наших котів захворів, і йому потрібна допомога доктора Айболита. Спробуємо створити клас Aibolit, який буде здатний лікувати і левів, і тигрів, і гепардів.
public class Aibolit {

   public void healLion(Lion lion) {

       System.out.println("Лев здоров!");
   }

   public void healTiger(Tiger tiger) {

       System.out.println("Тигр здоров!");
   }

   public void healCheetah(Cheetah cheetah) {

       System.out.println("Гепард здоров!");
   }
}
Здавалося б, проблему вирішено — клас написаний та готовий до роботи. Але що ми робитимемо, якщо захочемо розширити нашу програму? Зараз у нас всього 3 види: леви, тигри та гепарди. Але у світі існує понад 40 видів кішок. Уяви, що буде, якщо ми додамо до програми окремі класи для манулів, ягуарів, мейн-кунів, домашніх кішок та інших. Практика використання поліморфізму - 2Сама програма, звичайно, функціонуватиме, але ось до класуAibolitдоведеться постійно додавати нові методи для лікування кожного виду кішок, і в результаті він розростеться до небачених розмірів. Тут і проявляється властивість поліморфізму — «можливість працювати з декількома типами так, наче це той самий тип». Нам не потрібно створювати незліченну кількість методів, які робитимуть одне й те саме — лікувати кішку. Достатньо буде одного методу для всіх випадків відразу:
public class Aibolit {

   public void healCat(Cat cat) {

       System.out.println("Пациент здоров!");
   }
}
У метод healCat()ми можемо передавати і об'єкти Lion, і Tigerвони Cheetahвсі є Cat:
public class Main {

   public static void main(String[] args) {

       Aibolit aibolit = new Aibolit();

       Lion simba = new Lion();
       Tiger sherekhan = new Tiger();
       Cheetah chester = new Cheetah();

       aibolit.healCat(simba);
       aibolit.healCat(sherekhan);
       aibolit.healCat(chester);
   }
}
Виведення в консоль:

Пациент здоров!
Пациент здоров!
Пациент здоров!
Ось так наш клас Айболитможе працювати з різними типами, наче це той самий тип. Тепер давай розберемося з другою частиною: "при цьому поведінка об'єктів буде різною залежно від того, до якого типу вони належать". Тут також усе просто. У природі всі кішки бігають по-різному. Як мінімум, у них різниться швидкість бігу. Серед наших трьох вихованців гепард найшвидший, а тигр і лев бігають повільніше. Тобто вони відрізняються поведінкою. Поліморфізм не тільки дає можливість використовувати різні типи як один. Він при цьому ще дозволяє не забувати про їх відмінності та зберігає специфічну для кожного з них поведінку. Це можна зрозуміти на такому прикладі. Припустимо, після успішного одужання наші коти вирішабо на радостях трохи побігати. Додамо це в наш клас Aibolit:
public class Aibolit {

   public void healCat(Cat cat) {

       System.out.println("Пациент здоров!");
       cat.run();
   }
}
Спробуємо виконати той самий код для лікування трьох звірів:
public static void main(String[] args) {

   Aibolit aibolit = new Aibolit();

   Lion simba = new Lion();
   Tiger sherekhan = new Tiger();
   Cheetah chester = new Cheetah();

   aibolit.healCat(simba);
   aibolit.healCat(sherekhan);
   aibolit.healCat(chester);
}
І ось як виглядатиме результат:

Пациент здоров!
Лев бежит со швидкістью 80 км/ч
Пациент здоров!
Тигр бежит со швидкістью 60 км/ч
Пациент здоров!
Гепард бежит со швидкістью до 120 км/ч
Тут ми наочно бачимо, що специфічна поведінка наших об'єктів збереглася, хоча ми передали всіх трьох звірів у метод, узагальнивши кожного з них до Cat. Завдяки поліморфізму Java чудово пам'ятає, що це не просто три якихось коти, а саме лев, тигр і гепард, які бігають по-різному. У цьому полягає головна перевага використання поліморфізму - гнучкість . Коли нам потрібно створити якийсь загальний для багатьох типів функціонал — леви, тигри та гепарди перетворюються просто на «котів». Всі тварини різні, але в деяких ситуаціях - кіт є кіт, не має значення до якого виду він відноситься:) Ось тобі відеопідтвердження.
Коли ж це «узагальнення» не потрібно, і нам навпаки потрібно, щоб поведінка у видів відрізнялася, кожен тип поводиться по-своєму. Завдяки поліморфізму ти створюєш єдиний інтерфейс (набір методів) для широкого набору класів. За рахунок цього знижується складність програм. Якби ми навіть розширабо програму до 40 видів кішок, у нас все одно зберігся максимально простий інтерфейс — один метод run()для всіх 40 кішок.
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ