User Professor Hans Noodles
Professor Hans Noodles
41 уровень

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

Статья из группы Java Developer
Привет! Сегодня мы заканчиваем серию лекций о принципах ООП. На этом занятии поговорим о полиморфизме. Практика использования полиморфизма - 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 прекрасно помнит, что это не просто три каких-то кота, а именно лев, тигр и гепард, которые бегают по-разному. В этом заключается главное преимущество использования полиморфизма — гибкость. Когда нам нужно создать какой-то общий для многих типов функционал — львы, тигры и гепарды превращаются просто в «котов». Практика использования полиморфизма - 3Все животные разные, но в некоторых ситуациях — кот есть кот, без разницы к какому виду он относится:) Вот тебе видеоподтверждение.
Когда же это «обобщение» не требуется, и нам наоборот нужно, чтобы поведение у видов отличалось, каждый тип ведет себя по-своему. Благодаря полиморфизму, ты создаешь единый интерфейс (набор методов) для широкого набора классов. За счет этого снижается сложность программ. Если бы мы даже расширили программу до 40 видов кошек, у нас все равно сохранился бы максимально простой интерфейс — один метод run() для всех 40 кошек.
Комментарии (109)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Сергей Уровень 22, Москва, Россия
17 мая 2022
Котики веселят)
ARMA Уровень 28, Геленджик, Russian Federation
14 декабря 2021
Хорошая лекция, отличный пример!
Aleksei Reinsalu Уровень 19, Таллинн, Эстония
5 декабря 2021
А ведь несколько недель назад все начиналось с примитивных типов и оберток. Удивительно, даже если знаешь о самообмане, все равно от одиночных занятий ждешь больше, а от многих - меньше чем они дают.
NinaPi Уровень 23, Челябинск, Россия
21 ноября 2021
Самое доступное объяснение полиморфизма. Спасибо)
Natalia Уровень 3, Санкт-Петербург
18 ноября 2021
первая лекция, где полиморфизм так понятно объяснили!😸
Sergey Kornilov Уровень 38, Petropavlovsk, Казахстан
20 октября 2021
Вижу кота/собаку ставлю 👍
Nadezhda Goncharova Уровень 35
17 августа 2021
Один лайк за лекцию, один за котов :)
Илья Уровень 17, Ижевск
30 июня 2021
Я правильно понимаю, что без наследования нет полиморфизма? Или есть какие то другие ситуации?
Roksy Уровень 14, Краков, Польша
22 апреля 2021
Самая приятная лекция!!! ...благодаря вставке видео про "кот есть кот"😆😆😆
Тарас Шкарапут Уровень 17, Ульяновск, Россия
21 апреля 2021
15 лет спустя понял почему Chester любит Cheetas))