JavaRush/Java блог/Java Developer/Практика использования полиморфизма
Автор
Milan Vucic
Репетитор по программированию в Codementor.io

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

Статья из группы 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 прекрасно помнит, что это не просто три каких-то кота, а именно лев, тигр и гепард, которые бегают по-разному. В этом заключается главное преимущество использования полиморфизма — гибкость. Когда нам нужно создать какой-то общий для многих типов функционал — львы, тигры и гепарды превращаются просто в «котов». Все животные разные, но в некоторых ситуациях — кот есть кот, без разницы к какому виду он относится:) Вот тебе видеоподтверждение.
Когда же это «обобщение» не требуется, и нам наоборот нужно, чтобы поведение у видов отличалось, каждый тип ведет себя по-своему. Благодаря полиморфизму, ты создаешь единый интерфейс (набор методов) для широкого набора классов. За счет этого снижается сложность программ. Если бы мы даже расширили программу до 40 видов кошек, у нас все равно сохранился бы максимально простой интерфейс — один метод run() для всех 40 кошек.
Комментарии (140)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
{Java_Shark}
Уровень 19
около 3 часов назад
кошки есть кошки, все любят коробки)))
Роман
Уровень 17
10 декабря 2023, 15:46
Круто, спасибо! попробую сделать чтобы вмсто "пациент здоров" выводило "sherekhan здоров"
Anonymous #3361169
Уровень 47
1 декабря 2023, 03:42
👍
Denis Gritsay
Уровень 37
19 октября 2023, 20:06
ИМХО главное тут это - возможность использования полиморфизма определяется иерархией наследования классов, объекты которых передаются в качестве аргументов. то есть передали Кэт один результат, Лион иной ....
Николай
Уровень 20
14 сентября 2023, 16:27
классная аналогия!
Петро Пумпинець
Уровень 48
Expert
21 августа 2023, 14:22
Nice article, relaxing video
chess.rekrut
Уровень 25
21 августа 2023, 12:00
easy
Alexander Rozenberg
Уровень 32
25 июля 2023, 13:34
fine
24 июля 2023, 21:02
Благодаря этой лекции задумался: а не логичнее было бы называть классы с маленькой буквы, а обьекты с большой? Ведь в обычной жизни мы пишем "лев" с маленькой буквы, а "Симба" с большой а не наоборот
Пользователь Senior Pomidor
27 июля 2023, 12:45
Это же гениально!
No Name
Уровень 32
25 июня 2023, 12:45
+ статья в копилке