The Liskov Substitution Principle (LSP), named after computer scientist Barbara Liskov, is a cornerstone of SOLID design. It extends the concept of inheritance in object-oriented programming by emphasizing that objects of derived classes should be substitutable for objects of their base classes without altering the correctness of the program. In simpler terms, if a class is a subclass of another class, it should be able to replace its parent class seamlessly.
Please note, that there are two previous principles in SOLID:
To illustrate the LSP more effectively, let’s consider a classic example involving geometric shapes. We have a base class Shape
and two derived classes, Rectangle
and Circle
, each representing specific geometric shapes.
abstract class Shape { abstract public function area(); } class Rectangle extends Shape { private $width; private $height; public function __construct($width, $height) { $this->width = $width; $this->height = $height; } public function area() { return $this->width * $this->height; } } class Circle extends Shape { private $radius; public function __construct($radius) { $this->radius = $radius; } public function area() { return pi() * pow($this->radius, 2); } }
In this example, both Rectangle
and Circle
are subclasses of Shape
and implement the area()
method as required by the LSP. Now, let’s see how LSP plays a critical role:
function calculateArea(Shape $shape) { return $shape->area(); }
The calculateArea()
function accepts any object that is an instance of the Shape
class (or its subclasses). Thanks to LSP, we can confidently pass instances of Rectangle
or Circle
to this function, and it will calculate the area correctly without knowing the specific subclass it’s dealing with. This demonstrates the power of LSP in ensuring that derived classes can seamlessly replace their base class without causing unexpected issues.
By following the Liskov Substitution Principle, your code becomes more robust and adaptable to changes, as you can introduce new subclasses without disrupting the existing codebase.
In the next blog post, we’ll explore the Interface Segregation Principle (ISP), which emphasizes the importance of client-specific interfaces to avoid forcing clients to implement methods they don’t use.