Ответ
Полиморфизм — это принцип ООП, который позволяет использовать единый интерфейс для работы с объектами разных классов. Проще говоря, это способность объекта вести себя по-разному в зависимости от своего типа, но при этом отвечать на один и тот же вызов метода.
В Python полиморфизм проявляется несколькими способами:
1. Наследование и переопределение методов (Method Overriding)
Классический способ. Дочерний класс предоставляет свою реализацию метода, который уже существует в родительском классе.
class Shape:
def area(self):
raise NotImplementedError("Subclasses should implement this!")
class Square(Shape):
def __init__(self, side):
self.side = side
def area(self):
return self.side * self.side
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius * self.radius
# Единый интерфейс для разных объектов
for shape in [Square(5), Circle(3)]:
print(f"Площадь фигуры: {shape.area()}")
2. "Утиная типизация" (Duck Typing)
Ключевая особенность Python. Поведение объекта определяется наличием у него необходимых методов, а не его типом или классом. "Если это выглядит как утка и крякает как утка, то это утка".
class Duck:
def quack(self):
print("Quack!")
class Person:
def quack(self):
print("I'm quacking like a duck!")
# Функция работает с любым объектом, у которого есть метод quack()
def make_it_quack(obj):
obj.quack()
make_it_quack(Duck())
make_it_quack(Person())
Практический пример: Система обработки платежей
Полиморфизм позволяет создать гибкую систему, в которую легко добавлять новые способы оплаты, не изменяя основной код.
class PaymentGateway:
def process_payment(self, amount):
raise NotImplementedError
class StripeGateway(PaymentGateway):
def process_payment(self, amount):
print(f"Processing ${amount} payment via Stripe.")
class PayPalGateway(PaymentGateway):
def process_payment(self, amount):
print(f"Processing ${amount} payment via PayPal.")
# Основная логика не зависит от конкретной платежной системы
def execute_payment(gateway: PaymentGateway, amount: float):
gateway.process_payment(amount)
stripe = StripeGateway()
paypal = PayPalGateway()
execute_payment(stripe, 100.0)
execute_payment(paypal, 50.0) Ответ 18+ 🔞
А, полиморфизм! Ну это ж, блядь, классика, хуй с горы! Сейчас объясню, как это работает, а то у тебя, я смотрю, глаза уже квадратные.
Смотри, представь себе, что у тебя есть, допустим, команда «поехали». Ты её кричишь, и один чувак садится на велосипед, другой — в тачку, а третий, ёпта, на верблюда вскакивает. Все поехали, но каждый — по-своему, на своей хуйне. Вот это и есть полиморфизм, блядь! Одна команда, а реакция разная, в зависимости от того, кому и на чём ебашить.
В Питоне это вообще цветёт пиздопроебибна, потому что тут главное — не родословная, а умения. Есть у тебя метод quack() — значит, ты утка, и похуй, что ты на самом деле человек в костюме или радиоуправляемая игрушка.
Вот, смотри на примере, тут всё просто, как три копейки:
class УткаНастоящая:
def крякать(self):
print("Кря-кря, сука!")
class МужикПодвыпивший:
def крякать(self):
print("Я утка, блядь, кря-кря! Иди нахуй!")
# А эта функция — она вообще ни хуя не знает, кто перед ней.
# Ей главное, чтобы объект умел крякать.
def устроить_крякопаду(объект):
объект.крякать()
# И вот она, магия, ёбана!
устроить_крякопаду(УткаНастоящая())
устроить_крякопаду(МужикПодвыпивший())
Видишь? Функции устроить_крякопаду похуй, что ей передали. Она тупо вызывает метод .крякать(). А уж как он там реализован — это проблемы того, кто его писал. Главное, чтобы он был. Это и есть «утиная типизация» в чистом виде, ядрёна вошь! Если крякает — значит, сойдёт за утку.
Ну а если по-взрослому, с наследованием, то это когда ты в родительском классе объявляешь какой-нибудь метод, а в детях его переписываешь под себя. Как будто отец сказал: «Сынок, иди заработай». Один пошёл код писать, другой — пирожки продавать, а третий — у олигарха крышу моет. Все заработали, но способы, блядь, овердохуищно разные.
class Отец:
def заработать(self):
raise NotImplementedError("Иди работай, паразит!")
class Программист(Отец):
def заработать(self):
print("Сижу, блядь, в конторе, пишу код. Получил сотку.")
class Спекулянт(Отец):
def заработать(self):
print("Купил доллары по 60, продал по 120. Молодец, какой.")
# А тут общий счётчик, которому похуй, как ты заработал.
def посчитать_доход(работник: Отец):
работник.заработать()
посчитать_доход(Программист())
посчитать_доход(Спекулянт())
Вот и вся философия. Не нужно городить огород из проверок типов. Есть нужный метод — работаем. Нет — получишь ошибку, и сам виноват, пизда бородавчатая. Python так живёт, и, надо сказать, живёт неплохо. Главное — не выёбывайся и пиши методы так, чтобы их можно было вызывать одинаково. А там уже внутри твори, что хочешь.