Что такое полиморфизм в объектно-ориентированном программировании?

«Что такое полиморфизм в объектно-ориентированном программировании?» — вопрос из категории ООП, который задают на 33% собеседований Data Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Полиморфизм (в переводе — "много форм") — это один из ключевых принципов ООП, позволяющий объектам с одинаковым интерфейсом (или базовым типом) иметь различную реализацию и поведение. На практике это означает возможность использовать объекты разных классов через общий интерфейс, при этом конкретное поведение определяется реальным типом объекта во время выполнения (позднее связывание).

Основные формы полиморфизма:

  1. Полиморфизм подтипов (или наследования): Самый распространенный вид. Метод, объявленный в родительском классе или интерфейсе, переопределяется в дочерних классах.

    // Пример на Java
    abstract class Shape {
        abstract double area(); // Общий интерфейс
    }
    
    class Circle extends Shape {
        private double radius;
        Circle(double r) { this.radius = r; }
        @Override
        double area() { return Math.PI * radius * radius; } // Своя реализация
    }
    
    class Square extends Shape {
        private double side;
        Square(double s) { this.side = s; }
        @Override
        double area() { return side * side; } // Другая реализация
    }
    
    // Полиморфное использование:
    List<Shape> shapes = Arrays.asList(new Circle(5), new Square(4));
    for (Shape s : shapes) {
        System.out.println(s.area()); // Вызовется правильный метод для Circle и Square
    }
  2. Параметрический полиморфизм (обобщенное программирование / дженерики): Позволяет создавать типы и методы, которые работают с данными разных типов, оставаясь типобезопасными.

    // Обобщенный (полиморфный) контейнер
    class Box<T> {
        private T content;
        void set(T content) { this.content = content; }
        T get() { return content; }
    }
    // Один и тот же класс Box можно использовать для String, Integer и т.д.
    Box<String> stringBox = new Box<>();
    Box<Integer> intBox = new Box<>();
  3. Ad-hoc полиморфизм (перегрузка методов): Возможность иметь несколько методов с одним именем, но разными типами или количеством параметров. Компилятор выбирает подходящий метод на этапе компиляции.

    class Calculator {
        int add(int a, int b) { return a + b; }
        double add(double a, double b) { return a + b; } // Перегрузка
        String add(String a, String b) { return a + b; } // Еще одна перегрузка
    }

Преимущества полиморфизма:

  • Гибкость и расширяемость кода: Можно добавлять новые типы (например, Triangle), не меняя существующий код, работающий с Shape.
  • Упрощение взаимодействия: Клиентский код зависит от абстракции (Shape), а не от конкретных реализаций (Circle, Square).
  • Повторное использование: Общая логика может быть инкапсулирована в базовом классе или интерфейсе.

Видео-ответы