Принцип подстановки Барбары Лисков (Liskov Substitution Principle, LSP) – это один из пяти принципов SOLID, который формулируется следующим образом: объекты подклассов должны быть способны заменить объекты базовых классов без изменения желательных свойств программы. Этот принцип определен Барбарой Лисков и утверждает, что подклассы должны следовать тем же контрактам (интерфейсам) и предоставлять те же функциональные возможности, что и их родительские классы.
Ключевые концепции LSP:
- Совместимость с базовым классом: Если у нас есть класс и его подкласс, то подкласс должен быть способен использоваться везде, где используется базовый класс, без изменения логики программы.
- Подклассы могут дополнять поведение, но не изменять его: Подклассы могут добавлять новые методы и свойства, а также расширять функциональность базового класса, но они не должны изменять или нарушать предполагаемое поведение базового класса.
- Обеспечение инвариантов: Инварианты, определенные для базового класса, должны быть сохранены и в подклассах. Инварианты – это условия или ограничения, которые должны соблюдаться во всех состояниях объекта.
Пример нарушения LSP:
python
class Bird: def fly(self): pass class Ostrich(Bird): def fly(self): # Острич не умеют летать, поэтому метод fly переопределен, но не выполняет никаких действий pass
В этом примере, хотя класс Ostrich
является подклассом Bird
, он нарушает принцип LSP, так как переопределяет метод fly
и не выполняет действия, хотя ожидается, что все подклассы Bird
будут способны летать.
Пример, соблюдающий LSP:
python
class Bird: def move(self): pass class Sparrow(Bird): def move(self): print("Сквозь воздух") class Penguin(Bird): def move(self): print("Плавая в воде") class Ostrich(Bird): def move(self): print("Бегом по земле")
В этом примере каждый подкласс Sparrow
, Penguin
и Ostrich
соблюдает контракт базового класса Bird
, реализуя метод move
, который предоставляет разное поведение для каждого типа птицы. Это соблюдение принципа LSP, так как каждый подкласс можно использовать вместо базового класса Bird
без изменения логики программы.