Что такое полиморфизм?
Полиморфизм — свойство системы использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре объекта.
Ключевая особенность: объект производного класса можно использовать вместо объекта базового. Потомки могут изменять родительское поведение, даже если обращение к ним идёт по ссылке родительского типа.
Виды полиморфизма
- Ad hoc — функция ведёт себя по-разному для разных типов аргументов (например,
draw()рисует разные фигуры по-разному). - Параметрический — функция ведёт себя одинаково для аргументов разных типов (например,
add()одинаково кладёт в контейнер элементы разных типов).
Пример
Пользователь может звонить с любой модели телефона через единый метод:
Пример
public class User {
private String name;
public User(String name) {
this.name = name;
}
public void callAnotherUser(int number, AbstractPhone phone) {
// полиморфизм — тип phone определяется в рантайме
phone.call(number);
}
}
Разные реализации AbstractPhone:
Пример
public class ThomasEdisonPhone extends AbstractPhone {
@Override
public void call(int outputNumber) {
System.out.println("Вращайте ручку");
System.out.println("Сообщите номер абонента, сэр");
}
}
public class VideoPhone extends AbstractPhone {
@Override
public void call(int outputNumber) {
System.out.println("Подключаю видеоканал для абонента " + outputNumber);
}
}
Пример
AbstractPhone firstPhone = new ThomasEdisonPhone(1879);
AbstractPhone videoPhone = new VideoPhone(2018);
User user = new User("Андрей");
user.callAnotherUser(224466, firstPhone); // Вращайте ручку...
user.callAnotherUser(224466, videoPhone); // Подключаю видеоканал...
Один и тот же вызов callAnotherUser даёт разные результаты — конкретная реализация call выбирается динамически в зависимости от типа объекта. Это переопределение методов (method overriding): реализация метода базового класса заменяется в подклассе без изменения сигнатуры. Аннотация @Override заставляет компилятор проверить корректность сигнатуры.
Ключевое
- Полиморфизм снижает сложность — один интерфейс для разных реализаций.
- Выбор конкретного метода происходит в runtime, а не на этапе компиляции.
- В Java переопределение работает через виртуальные вызовы методов (динамическое связывание).