SOLID principle #3: Liskov Substitution (JavaScript)
Note: This post is part of a series of posts on the SOLID principles for software development (specifically in JavaScript). You can find them all at the following links:
1. Single responsibility
2. Open-closed
3. Liskov substitution
4. Interface segregation
5. Dependency inversion
The Liskov substitution principle states that any class should be substitutable for its parent class without unexpected consequences. In others words, if the classes Cat
and Dog
extend the class Animal
, then we would expect all of the functionality held within the Animal
class to behave normally for a Cat
and Dog
object.
A classic example of a Liskov substitution violation is the “square & rectangle problem”. In this problem, it is posed that a Square
class can inherit from a Rectangle
class. On the face of it, this makes sense; both shapes have two sides, and both calculate their area by multiplying their sides by each other.
But the problem arises when we try to utilise some Rectangle
functionality on a Square
object. Let’s look at an example:
In this example we initialise a Rectangle
and Square
, and output their dimensions. We then call the Rectangle.setHeight()
on the Square object, and output its dimensions again. What we find is that the square now has a different height than its length, which of course makes for an invalid square.
This can be solved, using polymorphism, an if statement in the Rectangle class, or a variety of other methods. But the real cause of the issue is that Square
is not a good child class of Rectangle
, and that in reality, perhaps both shapes should inherit from a Shape
class instead.