SOLID PrinciplesLiskov Substitution PrincipleHard⏱️ ~4 min

LSP and Other SOLID Principles: Integration

LSP does not exist in isolation. It works in concert with the other SOLID principles to create maintainable object-oriented designs. Understanding these interactions is crucial for interview discussions.

LSP + Open-Closed Principle (OCP)

OCP states classes should be open for extension but closed for modification. LSP makes OCP practical by ensuring new subclasses work with existing client code without changes.

FeeCalculator
+ calculate(duration): Money
HourlyFee
+ calculate(duration)
FlatRateFee
+ calculate(duration)
WeekendDiscountFee
+ calculate(duration)

Connection: We can add WeekendDiscountFee without modifying ParkingLot because LSP guarantees all calculators behave consistently. The system is closed for modification (no changes to existing classes) but open for extension (new fee strategies).

Interview Tip: When discussing OCP, mention that LSP is the enabler. Without LSP, you cannot safely extend through inheritance because new subclasses might break existing code, forcing modifications.

LSP + Interface Segregation Principle (ISP)

ISP states clients should not be forced to depend on interfaces they do not use. LSP violations often indicate ISP violations: a subclass cannot implement all parent methods because the parent interface is too broad.

Violates Both
Worker interface with work() and eat(). RobotWorker cannot eat, violating LSP and forcing dependency on unused method (ISP).
Satisfies Both
Separate Workable and Eatable interfaces. HumanWorker implements both, RobotWorker implements only Workable.

Solution approach:

  • First, identify operations that not all subtypes can support.
  • Second, extract those operations into separate interfaces.
  • Third, let subclasses implement only the interfaces they can honor (LSP compliant).
  • Fourth, client code depends only on the interfaces it needs (ISP compliant).

LSP + Single Responsibility Principle (SRP)

SRP states a class should have only one reason to change. LSP violations can indicate SRP violations when a parent class mixes multiple responsibilities, forcing some subclasses to implement irrelevant behavior.

// Violates both SRP and LSP
class Document {
save() { /* file operations */ }
print() { /* printer operations */ }
render() { /* display operations */ }
}

// EmailDocument cannot print physically
// Violates LSP by throwing in print()

Refactored design: Separate persistence (Saveable), rendering (Renderable), and printing (Printable) concerns. Each document type implements only the interfaces matching its responsibilities.

LSP + Dependency Inversion Principle (DIP)

DIP states high-level modules should depend on abstractions, not concretions. LSP ensures those abstractions are robust: you can safely depend on the base type knowing all implementations are substitutable.

class ParkingLot {
// Depends on abstraction (DIP)
constructor(feeCalculator: FeeCalculator) {
this.calculator = feeCalculator
}

calculateFee(duration) {
// Works for ANY FeeCalculator subtype (LSP)
return this.calculator.calculate(duration)
}
}

Key insight: DIP promotes depending on abstractions. LSP ensures those abstractions are dependable. Without LSP, you would need to check concrete types, defeating the purpose of DIP.

Practical Integration Example: Elevator System

Requirement: Design an elevator system with different elevator types (Standard, Express, Freight).
«interface»
Elevator
+ move(floor): Result
+ getCapacity(): int
+ getCurrentFloor(): int
«interface»
ExpressCapable
+ canSkipFloor(floor): boolean
«interface»
FreightCapable
+ maxWeight(): int
  • SRP: Each interface has single responsibility (basic movement, express capability, freight capability).
  • OCP: Can add new elevator types without modifying existing ones.
  • LSP: All Elevator implementations honor move/capacity/floor contracts.
  • ISP: Clients needing only basic elevator functions do not depend on express or freight interfaces.
  • DIP: Controller depends on Elevator abstraction, not concrete types.
Interview Tip: When asked about SOLID principles in general, use an example like this to show how they work together. Do not discuss each in isolation. Interviewers want to see you understand the relationships and trade-offs.

Common Interview Question

Question: "How do SOLID principles relate to each other? Give an example where multiple principles apply."

Strong answer structure:

"LSP and OCP work together: OCP lets us extend through inheritance, but only if LSP ensures new subclasses do not break existing code. Similarly, ISP and LSP are connected because overly broad interfaces force subclasses to implement methods they cannot support, violating LSP. In a parking lot design, we might have a FeeCalculator abstraction (DIP) with multiple strategies (OCP). Each strategy honors the calculation contract (LSP), and clients depend only on the calculator interface they need (ISP). The calculator itself has single responsibility (SRP): fee computation."
💡 Key Takeaways
LSP enables OCP by ensuring new subclasses work with existing client code
ISP violations often indicate LSP violations: overly broad interfaces force irrelevant implementations
SRP violations can lead to LSP violations when classes mix unrelated responsibilities
DIP relies on LSP: abstractions are only useful if all implementations are truly substitutable
In real designs, multiple SOLID principles apply simultaneously and reinforce each other
📌 Examples
1Elevator system demonstrating all SOLID principles working together
2FeeCalculator hierarchy showing LSP enabling OCP
3Worker-Robot example showing ISP and LSP intersection
← Back to Liskov Substitution Principle Overview