Полиморфизм в Python позволяет объектам разных классов реагировать на один и тот же метод по-разному, в зависимости от их типа. Это достигается за счет нескольких механизмов:
class Duck:
def quack(self):
return "Quack!"
class Cat:
def quack(self):
return "Meow!"
def make_sound(animal):
print(animal.quack())
duck = Duck()
cat = Cat()
make_sound(duck) # Output: Quack!
make_sound(cat) # Output: Meow!
class Animal:
def make_sound(self):
return "Generic animal sound"
class Dog(Animal):
def make_sound(self):
return "Woof!"
class Cat(Animal):
def make_sound(self):
return "Meow!"
animal = Animal()
dog = Dog()
cat = Cat()
print(animal.make_sound()) # Output: Generic animal sound
print(dog.make_sound()) # Output: Woof!
print(cat.make_sound()) # Output: Meow!
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14159 * self.radius * self.radius
class Square(Shape):
def __init__(self, side):
self.side = side
def area(self):
return self.side * self.side
circle = Circle(5)
square = Square(4)
print(circle.area()) # Output: 78.53975
print(square.area()) # Output: 16
# Trying to instantiate Shape directly would raise a TypeError:
# TypeError: Can't instantiate abstract class Shape with abstract methods area
def operate(x, y, operation):
return operation(x, y)
def add(x, y):
return x + y
def subtract(x, y):
return x - y
result1 = operate(5, 3, add) # Result: 8
result2 = operate(5, 3, subtract) # Result: 2
result3 = operate(5, 3, lambda x, y: x * y) # Result: 15
print(result1)
print(result2)
print(result3)
В целом, Python отдает предпочтение duck typing как основному способу реализации полиморфизма, поскольку он делает код более гибким и менее связанным с иерархией классов. Абстрактные базовые классы используются, когда необходимо обеспечить определенный интерфейс и гарантировать наличие определенных методов в подклассах.