Liskov Substitution Principle (LSP)
Definition
Objects of a derived class should be replaceable with objects of the base class without breaking application behavior.
👉 Child class should behave properly like parent class.
Purpose
- Ensure proper inheritance
- Avoid incorrect subclass behavior
- Improve polymorphism
- Prevent runtime issues
- Build reliable OOP design
Bad Example ❌
Parent Class
public class Bird
{
public virtual void Fly()
{
Console.WriteLine("Bird Flying");
}
}
Child Class
public class Ostrich : Bird
{
public override void Fly()
{
throw new Exception("Ostrich can't fly");
}
}
Problem
Bird bird = new Ostrich();
bird.Fly();
❌ Runtime failure.
👉 Child class breaks parent behavior.
This violates LSP.
Good Example ✅
Base Interface
public interface IBird
{
void Eat();
}
Flying Bird Interface
public interface IFlyingBird
{
void Fly();
}
Sparrow
public class Sparrow : IBird, IFlyingBird
{
public void Eat()
{
Console.WriteLine("Sparrow Eating");
}
public void Fly()
{
Console.WriteLine("Sparrow Flying");
}
}
Ostrich
public class Ostrich : IBird
{
public void Eat()
{
Console.WriteLine("Ostrich Eating");
}
}
Key Concept
Instead of:
Every bird must fly
We do:
Only flying birds implement Fly()
👉 Correct inheritance hierarchy.
Real-Time Scenario
Payment System:
PaymentMethod
↓
UPI
Card
Crypto
If one child behaves differently and breaks logic:
👉 LSP violation.
Advantages
- ✔ Proper inheritance design
- ✔ Safer polymorphism
- ✔ Prevents unexpected behavior
- ✔ Cleaner architecture
- ✔ Easier maintenance
Disadvantages
- ✖ Requires careful hierarchy design
- ✖ More interfaces/classes possible
When to Use
Use LSP when:
- Designing inheritance hierarchies
- Using polymorphism
- Creating reusable base classes
- Building extensible frameworks
Real Project Mapping (.NET + Angular)
| Feature | LSP Usage |
|---|---|
| Payment providers | LSP |
| Notification providers | LSP |
| Authentication handlers | LSP |
| Vehicle systems | LSP |
| File storage providers | LSP |
ASP.NET Core Real Example
ILogger logger =
new FileLogger();
OR
ILogger logger =
new DatabaseLogger();
👉 Any logger should work without breaking behavior.
LSP vs OCP
| LSP | OCP |
|---|---|
| Proper inheritance | Extend without modifying |
| Focus on child behavior | Focus on extensibility |
| Polymorphism correctness | Scalability |
Common LSP Violation Signs
- Child throws unsupported exceptions
- Child ignores parent behavior
- Extra unexpected restrictions
- if(type is ChildClass) checks everywhere
Pro Tip
LSP works best with:
- Interfaces
- Composition over inheritance
- Strategy Pattern
- Dependency Injection
Summary
LSP helps you:
- Build correct inheritance hierarchies
- Ensure safe polymorphism
- Avoid runtime surprises
👉 Perfect for:
- Enterprise applications
- Framework design
- Reusable components
- Extensible architectures
Comments
Post a Comment