Полиморфизм в Java

Полиморфизм в Java: один интерфейс — разное поведение. Разберём, как ссылка родительского типа вызывает методы потомков.

Полиморфизм (от греч. «много форм») — способность объектов разных классов отвечать на один и тот же вызов по-своему. Код работает с общим типом, а конкретное поведение определяется реальным объектом.

Ссылка родителя на объект потомка

Переменной родительского типа можно присвоить объект любого потомка. При вызове переопределённого метода выполнится версия реального объекта, а не типа переменной.

class Shape {
    double area() {
        return 0;
    }
}

class Circle extends Shape {
    double r;
    Circle(double r) { this.r = r; }
    @Override
    double area() {
        return 3.14159 * r * r;
    }
}

class Square extends Shape {
    double side;
    Square(double side) { this.side = side; }
    @Override
    double area() {
        return side * side;
    }
}

Единый код для разных типов

Главная польза: можно работать с массивом разных фигур через общий тип Shape — и каждая посчитает свою площадь сама.

Shape[] shapes = {
    new Circle(2),
    new Square(3)
};

for (Shape s : shapes) {
    System.out.println(s.area());   // вызовется нужная версия area()
}

Вывод:

12.56636
9.0

Это и есть сила полиморфизма: добавив новый класс Triangle extends Shape, цикл выше менять не нужно — он сразу заработает с новой фигурой.

Динамическое связывание

Java определяет, какой метод вызвать, во время выполнения, по реальному типу объекта — это называют динамическим связыванием. Поэтому s.area() в цикле даёт разные результаты, хотя тип переменной один.

Shape s = new Circle(1);
System.out.println(s.area());   // 3.14159 — версия Circle

s = new Square(2);
System.out.println(s.area());   // 4.0 — версия Square

Вывод:

3.14159
4.0

Коротко

  • Полиморфизм — один вызов, разное поведение в зависимости от реального объекта.
  • Переменной родительского типа можно присвоить объект потомка.
  • Вызывается версия метода реального объекта (динамическое связывание).
  • Позволяет писать код, работающий с целым семейством классов через общий тип.
Проверьте себя
1. Что произойдёт при вызове переопределённого метода через ссылку родительского типа?
AВызовется версия родителя
BВызовется версия реального объекта
CОшибка компиляции
DМетод не вызовется
2. В чём практическая польза полиморфизма?
AУскоряет программу
BПозволяет работать с семейством классов через общий тип
CУменьшает размер файла
DЗапрещает наследование
3. Когда Java определяет, какую версию метода вызвать при полиморфизме?
AПри компиляции
BВо время выполнения, по реальному типу объекта
CПри объявлении переменной
DНикогда — выбирает программист
Поддержать проект