Liskov Substitution Principle (LSP)

The Liskov Substitution Principle (LSP) is the third principle of the SOLID design principles. It states that objects of a parent class should be replaceable with objects of its child classes without affecting the correctness of the program.

In simple terms, any derived class should behave in such a way that it can be used anywhere its base class is expected. A child class must preserve the behavior and promises made by the parent class. It should not introduce unexpected behavior, throw unnecessary exceptions, or ignore the responsibilities defined by the base class.

When the Liskov Substitution Principle is followed, polymorphism becomes reliable because every subclass can safely substitute its parent without requiring special checks.

This document presents two practical examples demonstrating the implementation of the Liskov Substitution Principle in C++.

Example 1: Document Processing Engine

This example demonstrates a document management system where every file type guarantees that its contents can be read safely. Any file object can replace another without affecting the document processing system.

Program


Explanation

The ReadableFile class defines a contract that every derived class must provide a valid implementation of the readContent() function.

Both ConfigurationFile and SecureLogFile fulfill this contract by returning readable content.

The displayFileLogs() function works with the parent class pointer and never needs to know the actual type of file being processed. Any future class derived from ReadableFile can also be passed into this function without modifying the existing code.

This demonstrates the Liskov Substitution Principle because every child class can safely replace its parent.

Example 2: Bank Account Withdrawal System

This example demonstrates a banking system where different account types follow the same withdrawal contract. Every account can be processed by the ATM without causing unexpected failures.

Program


Explanation

The BankAccount class defines a standard withdrawal contract by returning true when a transaction succeeds and false when it fails.

The FixedDepositAccount class overrides the withdraw() function but still follows the same contract by safely returning false instead of causing an error or behaving unpredictably.

The processTransaction() function works correctly with both account types without checking the actual object type.

This demonstrates the Liskov Substitution Principle because every derived class preserves the behavior expected from the parent class.

Characteristics of the Liskov Substitution Principle

PropertyDescription
Core PrincipleObjects of derived classes should be replaceable with objects of their base class without affecting program correctness.
Primary GoalEnsure predictable behavior in inheritance hierarchies.
ImplementationAchieved through proper inheritance and method overriding while preserving the parent's behavioral contract.
Main BenefitImproves code reliability, maintainability, and safe polymorphic behavior.
Common ViolationChild classes changing expected behavior, throwing unexpected exceptions, or leaving inherited methods unsupported.

Conclusion

The Liskov Substitution Principle ensures that inheritance remains meaningful and reliable. Every derived class should preserve the behavior promised by its parent so that client code can use parent pointers or references without worrying about the actual object type. As demonstrated in the Document Processing Engine and Bank Account Withdrawal System examples, following LSP leads to predictable, maintainable, and robust object-oriented software in C++.