Liskov Substitution — Subtypes must honour the parent contract
Subtypes must honour the base contract — no surprise side effects. · If tests written for the base fail on a subtype, LSP is broken.
Watch
Watch, then scroll down for code and practice.
In code
interface Bird {
move(): void;
}
class Sparrow implements Bird {
move() {
/* fly */
}
}
// Bad: Penguin implements Bird { move() { fly } } — violates expectation.📘 Key ideas
The principle
If S is a subtype of T, objects of type S can replace T without breaking the programme's correctness.
The classic violation
Square extends Rectangle. Callers expect setWidth(5) to not affect height. Square breaks this — it must keep width == height.
Test
Write tests against the base class contract. Run the same tests on subclasses. If any fail — LSP is violated.
The fix
Don't extend when the subtype can't honour the full contract. Prefer an immutable Shape interface: area() and perimeter() only, no setters.
🧠 Practice — Apply What You Learned
SRP: Fix the Overloaded Logger
You are given a Logger class that does too much: it formats log messages, filters by level…
OCP: Extend Discounts Without Modifying
A PriceCalculator class uses a long if-else chain to apply discounts: if user is Student, …
LSP: The Square–Rectangle Problem
The classic LSP violation: Square extends Rectangle. Since a square's width and height mus…
ISP: Break the Fat Worker Interface
A Worker interface has four methods: work(), eat(), sleep(), requestLeave(). HumanWorker i…
DIP: Decouple the Database Layer
UserService directly instantiates MySQLDatabase inside its constructor: `this.db = new MyS…
Logger / Logging Framework
Design a flexible logging framework that supports multiple log levels, formatters, and out…
Payment Gateway
Design a payment processing system that handles transactions across multiple payment metho…
🚀 Now apply what you learned
Pick a problem above, write your solution, and get AI feedback on your design.
Start Practice →