Проверяет понимание плюсов и минусов двух основных подходов к переиспользованию кода.
Наследование создаёт жёсткую связь между классами (изменения в родителе влияют на потомков).
Композиция гибче: можно динамически менять используемые объекты (например, подставлять разные реализации).
Проблемы наследования:
Хрупкость: Изменение родительского класса может сломать дочерние.
Множественное наследование: Может привести к конфликтам методов (например, "алмаз смерти").
Преимущества композиции:
Гибкость: Можно заменить компонент на лету (например, car.engine = ElectricEngine()).
Тестируемость: Легко подменять реальные объекты mock-ами.
Пример композиции vs наследования:
# Наследование (менее гибко)
class Bird:
def fly(self):
print("Лечу")
class Penguin(Bird): # Пингвин не может летать, но наследует fly()!
pass
# Композиция (гибче)
class FlyingBehavior:
def fly(self):
print("Лечу")
class Bird:
def __init__(self, fly_behavior=None):
self.fly_behavior = fly_behavior
def fly(self):
if self.fly_behavior:
self.fly_behavior.fly()
penguin = Bird() # Пингвин без fly_behavior не может летать.