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

Ответ

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

В 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()) # Выведет: Лечу по воздуху

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

Ответ 18+ 🔞

А, ну это ж про полиморфизм, ёпта! Такая хуйня, когда у тебя куча разных объектов, а они все делают одно и то же, но по-своему, блядь. Как в жизни: один чувак говорит «привет» — ты ему «здарова», а другой говорит «салют» — ты ему «хай». Суть одна — поздороваться, а форма разная. Вот это и есть полиморфизм, нахуй.

В Питоне это вообще просто, потому что тут утиная типизация, блядь. Не надо никого насиловать наследованием, если не хочешь. Главное — чтобы объект умел делать то, что от него ждут. Если он крякает как утка — значит, утка и есть, даже если это на самом деле хомяк в утиной маске, ебать мои старые костыли.

Вот смотри, пример классический, через наследование. Делаем базовый класс, типа «Животное». Оно должно уметь говорить, но как именно — хер его знает. Поэтому метод speak просто поднимает ошибку, мол, «иди нахуй, реализуй сам».

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())  # Выведет: Мяу!

Вот тебе и полиморфизм в действии. Одна функция, а работает с разными типами. Красота, блядь!

А теперь второй способ, чисто питонячий — утиная типизация. Тут вообще наследование не обязательно. Просто берём три разных класса, которые даже друг друга в рот не видели, но у всех есть метод move().

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()) # Выведет: Лечу по воздуху

Вот и весь полиморфизм, блядь. Гибко, расширяемо, и код читается как похабный анекдот — легко и с удовольствием. Главное — чтобы интерфейс (набор методов) был одинаковый, а что там внутри творится — это уже твои личные проблемы, в рот меня чих-пых.