Liskov substitution principle
Principle
When extending a class, consider that you should be able to pass objects of the subclass in place of objects of the parent class without breaking the client code.
I've stated this principle informally; if you look it up on Wikipedia for instance, you will find formal descriptions such as
caution
Let Ï•(x)
be a property provable about objects x
of type T
. Then Ï•(y)
should be true for objects y
of type S
where S
is a sub-type of T
.
All this, is a fancy way of saying that every subclass/derived class should be substitutable for their base/parent class. In other words, a subclass should not break the expectations (code contracts) set by its super-class.1
Let's see an example to better understand the Liskov Substitution Principle (LSP). Consider the following implementation of Rectangle
class.
Since a square is a rectangle (mathematically speaking), we decide to implement Square
as a subclass of Rectangle
. We override setWidth
and setHeight
and we can reuse the implementation of getArea
.
tip
With this overriding of setWidth
and setHeight
-- to set both dimensions to the same value -- instances of Square
remain mathematically valid squares.
The bad news is that making Square
a subtype of Rectangle
violates the Liskov Substitution Principle. Here is why:
LSP is violated because if we pass an object of Square
to clientMethod
(which we can since Square
is a subtype of Rectangle
) the assertion in clientMethod
will fail. In other words, the expected behavior of super type is not maintained.
So what is the solution? Well, you can simply make two separate classes: Rectangle
and Square
.
You could use composition to reuse the code in Rectangle
:
Case in point
- LSP is all about well-designed inheritance. If you cannot substitute your baseclass with a subclass without things going wrong, then it means you used inheritance incorrectly.
- Inheritance seems like a cool idea; you get to create a hierarchy of types and reuse your code. But, it’s easy to abuse inheritance. So, don't overdo it; especially consider composition over inheritance!
- A closely related principle in software development is called "Design by contract". ↩