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

Ответ

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

В Python полиморфизм реализуется преимущественно через:

  1. Наследование и переопределение методов: Дочерние классы переопределяют методы родительского класса, предоставляя свою специфическую реализацию.
  2. Утиную типизацию (Duck Typing): Если объект "ходит как утка и крякает как утка", то для нас он "утка". Python не проверяет типы объектов во время компиляции, а лишь наличие необходимых методов или атрибутов во время выполнения.

Пример 1: Полиморфизм через наследование и переопределение методов

class Animal:
    def speak(self):
        # Базовый метод, который должен быть переопределен
        raise NotImplementedError("Метод 'speak' должен быть реализован в дочернем классе")

class Dog(Animal):
    def speak(self):
        return "Гав!"

class Cat(Animal):
    def speak(self):
        return "Мяу!"

# Функция, которая работает с любым объектом, имеющим метод speak()
def make_sound(animal: Animal):
    print(animal.speak())

# Использование полиморфизма
make_sound(Dog())  # Выведет: Гав!
make_sound(Cat())  # Выведет: Мяу!

Пример 2: Полиморфизм через утиную типизацию

class Car:
    def move(self):
        return "Еду по дороге"

class Ship:
    def move(self):
        return "Плыву по воде"

class Plane:
    def move(self):
        return "Лечу по воздуху"

# Функция, которая принимает любой объект, имеющий метод move()
def transport(obj):
    print(obj.move())

# Использование утиной типизации
transport(Car())   # Выведет: Еду по дороге
transport(Ship())  # Выведет: Плыву по воде
transport(Plane()) # Выведет: Лечу по воздуху

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