Show in graph

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.

Code example
Bad example
Python
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)
Good example
Python
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.