Card 09/ 09
Recap: Liskov Substitution
A subtype must work wherever its parent does, and a type check in the caller says it does not.
The Liskov substitution principle keeps inheritance safe for the code that uses it.
- A subtype must work anywhere its parent is expected. Matching method names is not enough; the behaviour must match what callers rely on.
- The failure appears in the caller, in code that was correct, which is why it is hard to trace.
- Three rules make it checkable: do not strengthen preconditions, do not weaken postconditions, preserve invariants. Ask for no more, promise no less.
- Fix the abstraction, not the subclass. If some children cannot keep a promise, move the promise to a narrower parent, as
flymoved toFlyingBird. - Real-world "is a" does not decide inheritance. A square is a rectangle in geometry but not in mutable code.
- Libraries make trade-offs. Java's
List.addis an optional operation, soList.ofcan throw from it. - A type check in the caller is a symptom. It means a subtype already broke its parent's promise.
← → move through sections and cards