Полиморфизм — возможность использовать одно и то же имя для разных реализаций методов или конструкторов.
В Java полиморфизм реализуется с помощью перегрузки (overloading) и переопределения (overriding).
Перегрузка позволяет в пределах одного класса создавать несколько методов (или конструкторов) с одинаковым именем, а отличаться они будут колличеством или типом параметров.
Возникает закономерный вопрос: когда мы воспользуемся одним из таких методов с одинаковым именем, как компилятор определяет, какую реализацию выбрать? Ответ прост — он делает это на основании числа и типов переданных аргументов.
Рассмотрим пример перегрузки конструкторов:
Вывод:

Даже несмотря на то, что у всех конструкторов одинаковое имя Animal
, компилятор различает их по параметрам. Это и есть пример перегрузки конструктора, которая является одной из форм полиморфизма.
Однако помним, что полиморфизм может применяться не только к конструкторам, но и к методам.
Переопределение метода родителя в классе-наследнике
Под полиморфизмом также понимается переопределение метода родительского класса в классе-наследнике.
Например, ниже в классе Animal
(Животное) определён метод move()
(Движение), который просто сообщает, что животное может двигаться. Его реализация — вывод строки "The animal moves."
— является универсальной и подходит для любого животного. Такой метод вполне может использоваться без изменений в классах-наследниках.
Однако в некоторых случаях желательно уточнить поведение метода. Например, если мы создадим класс Cat
(Кот), который наследуется от Animal
, то он унаследует и метод move()
. Но в контексте кошки может быть полезно уточнить поведение этого метода, поскольку, разумеется, куда лучше, если move()
будет описывать именно движения, характерные для кошки — например, "The cat gracefully walks and jumps."
— а не просто общее "The animal moves."
В таких случаях метод move()
можно переопределить в классе-наследнике, чтобы сделать поведение более конкретным и реалистичным.
Это и есть проявление полиморфизма: один и тот же метод, но разная реализация в разных классах.
Рассмотрим пример:
Вывод:

Каждое животное, наследующее класс Animal
, может по-своему переопределить метод move()
. Так, у птицы это может быть “летает”, у собаки — “бежит”, и так далее.
Переопределение методов — мощный механизм, позволяющий делать поведение объектов более точным и соответствующим их конкретному типу, оставаясь при этом в рамках единой абстракции.
Table of Contents
Абстрактный класс
Разберитесь с абстрактными классами в Java: общие концепты, абстрактные методы, ключевое слово abstract. Практические примеры.
Интерфейсы в Java
Изучите интерфейсы в Java: как определять поведение классов, ключевые слова interface и implements, отличие от абстрактных классов. Примеры кода и сравнение.
Статические поля
Статические поля и методы в Java: как они работают, общие для всех объектов класса, вызов без создания экземпляра и практические примеры кода.