# Liskov Substitution Principle (LSP) The **Liskov Substitution Principle (LSP)** states that subtypes must be substitutable for their base types without altering the correctness of the program. If code works correctly with an object of type `T`, it must continue to work when given any object of a subtype `S` of `T` — no surprises, no special casing, no broken expectations. Formulated by [[Barbara Liskov]] in her 1987 OOPSLA keynote *"Data Abstraction and Hierarchy"* and refined with Jeannette Wing in the 1994 paper *"A Behavioral Notion of Subtyping"*. LSP is the "L" in the [[SOLID Principles]]. ## Formal Statement > *Let φ(x) be a property provable about objects x of type T. Then φ(y) should be true for objects y of type S, where S is a subtype of T.* > — Liskov & Wing, 1994 In plain terms: a subtype must honor the contract of its supertype. ## Behavioral Rules A subtype `S` of `T` must satisfy: | Rule | Meaning | |------|---------| | **Preconditions** | Cannot be strengthened in `S` (subtype must accept everything `T` accepts) | | **Postconditions** | Cannot be weakened in `S` (subtype must guarantee at least what `T` guarantees) | | **Invariants** | Must be preserved by `S` | | **Exceptions** | `S` should not throw new exceptions not declared by `T` | | **History constraint** | `S` should not allow state changes that `T` forbids | This is the core of [[Design by Contract]] applied to inheritance. ## Classic Violation: Square/Rectangle A `Square` "is-a" `Rectangle` mathematically, but if `Rectangle` exposes `setWidth` and `setHeight` independently, a `Square` cannot satisfy that contract — setting width must also set height. Code expecting independent setters breaks. The geometric "is-a" lies; the behavioral contract doesn't substitute. ## Common Violations - Overriding a method to throw `UnsupportedOperationException` - Adding strict input validation in a subclass that the base class accepts - Returning `null` where the base class guarantees non-null - Subclass requires callers to know it's not really the base type ("if instanceof X then...") ## Why It Matters LSP makes polymorphism trustworthy. Without it, every consumer needs to know which concrete subtype it has, which destroys the abstraction. Code becomes brittle to inheritance changes; new subtypes silently break callers; reasoning about behavior requires the entire subtype hierarchy in your head. ## Beyond Inheritance The principle generalizes to any "is-a" relationship: interfaces, traits, type classes, structural types, even API contract evolution. A new API version is a "subtype" of the old one and must remain substitutable for clients — this is why backward compatibility is LSP for APIs. ## References - Barbara Liskov, "Data Abstraction and Hierarchy" (OOPSLA 1987 keynote) - Liskov & Wing, "A Behavioral Notion of Subtyping" (ACM TOPLAS, 1994) - Robert C. Martin, "Clean Architecture" (2017) ## Related - [[Barbara Liskov]] - [[SOLID Principles]] - [[Design by Contract]] - [[Composition over Inheritance]] - [[Loose Coupling]]