SOLID Principles • Liskov Substitution PrincipleMedium⏱️ ~3 min
LSP Structure: Class Hierarchy and Contracts
LSP compliance requires understanding the contract between classes. The subclass must honor all promises made by the superclass while being free to add additional functionality.
Valid LSP Hierarchy
PaymentMethod
- amount: Money
+ processPayment(): Result
+ refund(): Result
+ refund(): Result
▲
CreditCard
- cardNumber: String
+ processPayment(): Result
+ refund(): Result
+ refund(): Result
BankTransfer
- accountNumber: String
+ processPayment(): Result
+ refund(): Result
+ refund(): Result
Both subclasses honor the PaymentMethod contract. Any code using PaymentMethod works with both CreditCard and BankTransfer without modification.
LSP Violation Example
Rectangle
- width: int
- height: int
- height: int
+ setWidth(w: int): void
+ setHeight(h: int): void
+ getArea(): int
+ setHeight(h: int): void
+ getArea(): int
▲
Square
- side: int
+ setWidth(w: int): void
+ setHeight(h: int): void
+ getArea(): int
+ setHeight(h: int): void
+ getArea(): int
Why this violates LSP: When Square overrides setWidth() or setHeight(), it must set both dimensions to maintain the square invariant. This breaks the expected behavior:
rectangle = new Rectangle()
rectangle.setWidth(5)
rectangle.setHeight(10)
assert rectangle.getArea() == 50 // Works
rectangle = new Square() // Substitute subtype
rectangle.setWidth(5)
rectangle.setHeight(10)
assert rectangle.getArea() == 50 // FAILS! Returns 100
rectangle.setWidth(5)
rectangle.setHeight(10)
assert rectangle.getArea() == 50 // Works
rectangle = new Square() // Substitute subtype
rectangle.setWidth(5)
rectangle.setHeight(10)
assert rectangle.getArea() == 50 // FAILS! Returns 100
Contract Elements
- Method signature: Parameters and return types must match
- Exceptions: Subclass cannot throw new checked exceptions
- Return values: Must satisfy postconditions of parent
- Input parameters: Cannot be more restrictive than parent
💡 Key Takeaways
✓Subclass must honor all contracts established by the superclass
✓Method signatures, exceptions, and return types must be compatible
✓Strengthening preconditions or weakening postconditions violates LSP
✓Rectangle-Square is a classic example of mathematical vs behavioral relationships
✓Valid hierarchies allow seamless substitution without client code changes
📌 Examples
1PaymentMethod hierarchy where all subtypes honor process and refund operations
2Rectangle-Square problem demonstrates behavioral incompatibility despite mathematical relationship