все Python 3ООПпонятие
Полиморфизм
полиморфизм
Один интерфейс — разные реализации. В Python достигается переопределением методов и duck typing.
Синтаксис
for obj in objects:
obj.method() # разные реализации
В Python объектам не обязательно иметь общего предка — хватает совпадающих имён методов (duck typing), поэтому полиморфизм работает и вовсе без наследования. Базовый класс с NotImplementedError — только соглашение; чтобы отсутствие метода ловилось при создании объекта, а не при его вызове, используйте abc.ABC с @abstractmethod.
Примеры
class Shape:
def area(self):
raise NotImplementedError
class Circle(Shape):
def __init__(self, r):
self.r = r
def area(self):
import math
return math.pi * self.r**2
class Rectangle(Shape):
def __init__(self, w, h):
self.w = w; self.h = h
def area(self):
return self.w * self.h
shapes = [Circle(3), Rectangle(4,5)]
for s in shapes:
print(round(s.area(), 2)) # → 28.27 / 20
# Duck typing
class Dog:
def speak(self):
return 'Woof!'
class Cat:
def speak(self):
return 'Meow!'
class Duck:
def speak(self):
return 'Quack!'
for animal in [Dog(), Cat(), Duck()]:
print(animal.speak()) # → Woof! Meow! Quack!
# Общая функция — полиморфный вызов
def make_sound(animal):
print(animal.speak())
make_sound(Dog()) # → Woof!
make_sound(Duck()) # → Quack!
# Перегрузка операторов — полиморфизм
class Vector:
def __init__(self, x):
self.x = x
def __add__(self, other):
return Vector(self.x + other.x)
class Matrix:
def __init__(self, data):
self.data = data
def __add__(self, other):
return Matrix([[a + b for a, b in zip(r1, r2)]
for r1, r2 in zip(self.data, other.data)])
print((Vector(1)+Vector(2)).x) # → 3
# isinstance + полиморфизм
def describe(obj):
if isinstance(obj, list):
return f'list of {len(obj)}'
elif isinstance(obj, str):
return f'string: {obj!r}'
else:
return f'other: {type(obj).__name__}'
print(describe([1,2,3])) # → list of 3
print(describe('hi')) # → string: 'hi'
См. также
Открыть в полном глоссарииdocs.python.orgСообщить о неточности