L · SOLID
Liskov Substitution
A subtype must be usable anywhere its base type is expected — without breaking the caller's assumptions.
✗ Problem
↑ extends
Square extends Rectangle breaks callers
A Square forces width and height to move together. Any code written against Rectangle's contract can now silently misbehave.
class Square extends Rectangle {
setWidth(s) { this.w = this.h = s; }
setHeight(s) { this.w = this.h = s; }
}
function grow(r) {
r.setWidth(5);
r.setHeight(4);
return r.area();
}
grow(new Rectangle()) // → 20 ✓
grow(new Square()) // → 16 ✗ side got forced
Rectangle
w, h vary independently
Square
setWidth() also sets h
A Square is NOT substitutable for a Rectangle — same
grow() call, two different answers. LSP violated.
✓ Refactor
↑
Stop forcing an is-a that isn't true
Introduce a Shape abstraction. Rectangle and Square each implement
it independently — siblings, not parent and child.
interface Shape { area(): number }
class Rectangle implements Shape {
constructor(w, h) { this.w = w; this.h = h; }
area() { return this.w * this.h; }
}
class Square implements Shape {
constructor(side) { this.side = side; }
area() { return this.side ** 2; }
}
Shape
interface · area()
Rectangle
w, h
Square
one side
✓ See it live
Run
↓
Run grow() against each subtype
Same function, same two calls — setWidth(5) then
setHeight(4). Pick which subtype gets passed in.
function grow(r) {
r.setWidth(5);
r.setHeight(4);
return r.area();
}
?
passed to grow(r)
area = —
—
Pick a subtype to pass into grow(r).
✓ Takeaway
Substitutable means the contract holds
- Preconditions a subtype requires must be no stronger than the base's.
- Postconditions a subtype guarantees must be no weaker than the base's.
- Invariants of the base (like "width and height vary independently") must be preserved.
- Fix: model reality correctly, or favor composition, instead of forcing inheritance onto a relationship that isn't truly is-a.
🎯 Related: a Proxy
must be substitutable for the real subject it stands in for — same idea, applied to delegation.
Back to all topics →