principletypescriptMajor
SOLID — Liskov Substitution Principle: Subtypes Must Honor the Contract
Viewed 0 times
Liskov substitutionLSPSOLIDsubtype contractpolymorphismrectangle squarebehavioral contract
Problem
A subclass overrides a method and changes its behavior in a way that breaks callers written against the base class. Code that works with
Bird breaks when you pass a Penguin (a subclass that cannot fly).Solution
Subclasses must fulfill the behavioral contract of their base class: same preconditions or weaker, same postconditions or stronger, no new exceptions. If a subclass cannot honor the contract, it should not inherit.
// LSP violation: ReadOnlyList extends List but throws on mutating operations
class List<T> {
private items: T[] = [];
add(item: T): void { this.items.push(item); } // postcondition: item is added
get(index: number): T { return this.items[index]; }
}
class ReadOnlyList<T> extends List<T> {
add(_item: T): void { throw new Error('Read only!'); } // VIOLATION
}
// Fix: use composition and separate interfaces
interface ReadableList<T> { get(index: number): T; }
interface MutableList<T> extends ReadableList<T> { add(item: T): void; }
class ArrayList<T> implements MutableList<T> {
private items: T[] = [];
add(item: T) { this.items.push(item); }
get(index: number) { return this.items[index]; }
}
class ImmutableList<T> implements ReadableList<T> {
constructor(private items: T[]) {}
get(index: number) { return this.items[index]; }
}Why
LSP is what makes polymorphism trustworthy. If subtypes can silently break caller assumptions, the abstraction provides false safety. Violations usually signal a wrong inheritance relationship.
Gotchas
- The classic Rectangle/Square example: Square extends Rectangle but cannot honor the contract that setting width and height independently works — Square should not inherit Rectangle.
- TypeScript's structural typing allows unrelated types to satisfy an interface. LSP still applies: the behavioral contract must be honored, not just the structural signature.
- Strengthening preconditions (requiring more from the caller) or weakening postconditions (delivering less) are both LSP violations.
Revisions (0)
No revisions yet.