Привет!
Сегодня мы заканчиваем серию лекций о принципах ООП. На этом занятии поговорим о полиморфизме.
Полиморфизм — это возможность работать с несколькими типами так, будто это один и тот же тип. При этом поведение объектов будет разным в зависимости от того, к какому типу они принадлежат.
Давай рассмотрим это утверждение подробнее.
Начнем с первой части: «возможность работать с несколькими типами так, как будто это один и тот же тип». Как разные типы могут при этом быть одним и тем же? Звучит немного странно :/
На самом деле все просто. К примеру, такая ситуация возникает при обычном использовании наследования. Посмотрим, как это работает.
Допустим, у нас есть простой родительский класс
Сама программа, конечно, будет функционировать, но вот в класс
Когда же это «обобщение» не требуется, и нам наоборот нужно, чтобы поведение у видов отличалось, каждый тип ведет себя по-своему.
Благодаря полиморфизму, ты создаешь единый интерфейс (набор методов) для широкого набора классов. За счет этого снижается сложность программ.
Если бы мы даже расширили программу до 40 видов кошек, у нас все равно сохранился бы максимально простой интерфейс — один метод

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 видов кошек. Представь, что будет, если мы добавим в программу отдельные классы для манулов, ягуаров, мейн-кунов, домашних кошек и всех остальных.

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 прекрасно помнит, что это не просто три каких-то кота, а именно лев, тигр и гепард, которые бегают по-разному.
В этом заключается главное преимущество использования полиморфизма — гибкость. Когда нам нужно создать какой-то общий для многих типов функционал — львы, тигры и гепарды превращаются просто в «котов».
Все животные разные, но в некоторых ситуациях — кот есть кот, без разницы к какому виду он относится:) Вот тебе видеоподтверждение.
run()
для всех 40 кошек.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ