Software → Software Design
LSP
Subtypes should be usable anywhere their base types are expected without breaking correctness.
Motivation
LSP solves the problem of inheritance hierarchies that look correct but break when a subtype is used through the base type. A subtype must preserve the expectations of the abstraction it claims to implement.
Where it fits
LSP belongs to SOLID and software design. It depends on polymorphism and is especially important when code relies on base classes or interfaces.
class PaymentMethod: def charge(self, amount): raise NotImplementedErrorclass DisabledPaymentMethod(PaymentMethod): def charge(self, amount): raise RuntimeError("cannot charge")class CheckoutService: def checkout(self, payment_method, total): payment_method.charge(total)class PaymentMethod: def charge(self, amount): raise NotImplementedErrorclass CardPayment(PaymentMethod): def charge(self, amount): print(f"Charging card for {amount}")class CheckoutService: def checkout(self, payment_method, total): payment_method.charge(total)Common mistakes
- Using inheritance only because two classes share fields.
- Creating subtypes that weaken guarantees or throw surprising exceptions.