Mastering "L" in S.O.L.I.D
Liskov Substitution Principle

“Objects of a superclass should be replaceable with objects of its subclasses without breaking the application’s behavior.”
💡 Real-Life Example
Think of this:
You have a class Bird that can fly().
You create a subclass Sparrow (it can fly ✅).
Then you create another subclass Ostrich (it cannot fly ❌).
If your program expects all Birds to fly, using Ostrich will break your logic — which violates LSP.
So, Ostrich should not extend Bird if Bird assumes “can fly”.
// ❌ Violates LSP
class Bird {
void fly() {
System.out.println("Flying...");
}
}
class Sparrow extends Bird {} // OK
class Ostrich extends Bird { // Problem
@Override
void fly() {
throw new UnsupportedOperationException("Ostrich can't fly!");
}
}
// ✅ Correct Approach
interface Bird {}
interface FlyingBird extends Bird {
void fly();
}
class Sparrow implements FlyingBird {
public void fly() {
System.out.println("Flying...");
}
}
class Ostrich implements Bird {
// Ostrich doesn't fly, but still a bird — no LSP violation.
}
More Examples:-
🧾 1. Payment System Example (E-commerce App)
Imagine you have a PaymentService interface that processes payments.
You have classes like:
CreditCardPayment
PayPalPayment
UPIPayment
Each one should behave like a payment service — if one fails to behave differently (e.g., throws error on same method), it violates LSP.
interface PaymentService {
void pay(double amount);
}
class CreditCardPayment implements PaymentService {
public void pay(double amount) {
System.out.println("Paid " + amount + " using Credit Card");
}
}
class PayPalPayment implements PaymentService {
public void pay(double amount) {
System.out.println("Paid " + amount + " using PayPal");
}
}
// ❌ Violating LSP
class CashOnDeliveryPayment implements PaymentService {
public void pay(double amount) {
throw new UnsupportedOperationException("Cash payment not supported online!");
}
}
Here, CashOnDeliveryPayment breaks LSP because it cannot be used wherever a PaymentService is expected.
It will crash the program.
✅ Fix: Don’t force it into the same inheritance; maybe separate interfaces:
interface OnlinePaymentService extends PaymentService {}
interface OfflinePaymentService {
void collectCash();
}
📦 2. Inventory System Example
🔹 English:
Suppose your app has a base class InventoryItem.
You create child classes like:
PerishableItem(milk, fruits)NonPerishableItem(phone, laptop)
If the parent class has a method like calculateExpiryDate(), and non-perishable items can’t have expiry, that’s an LSP violation.
✅ Fix → Move expiry logic to a subclass or new interface.




