LSP: Liskov Substitution Principle

Hicham BEN KACHOUD
3 min readApr 1, 2022

This principle was named after Barbara Liskov, who defined it in 1987 in her work Data abstraction and hierarchy.

Introduction

The Liskov Substitution Principle is one of 5 principles of Object-Oriented Design. They are :

In this post, I will focus on LSP, and I will explain the other principles in future articles.

Definition

Uncle Bob defines the principle as:

Subtypes must be substitutable for their base types.

A Superclass object should be replaceable with a Subclass object without breaking the functionality of the software.

The Substitution Principle is a set of checks that helps predict whether a class will still compatible with code that worked with parent class objects. This concept is critical when you are developing libraries and frameworks.

Using this principle, the code should not depend on the class hierarchy. Therefore, it should not use a cast or an “instanceof” operator.

This principle imposes some rules on subclasses, and more specifically on their methods.

Rules

Let’s look at some of this rules in details:

  • Method parameters types

Subclass method parameter types must match or be more abstract than parent class method parameter types.

LSP — Method parameters type
  • Method return type

The return type in a method of a subclass must match or be a subtype of the return type of the parent class method.

As you can see, the pre-requirements for a method’s return types are the inverse of the parameter types.

LSP — Method return type
  • Precondition

A subclass should not enforce preconditions.

LSP — PreCondition

There are other rules like:

  • A subclass should not weaken postconditions.
  • The invariants of a parent class must be preserved.
  • A subclass should never modify the values of the private attributes of a parent class (using Reflection).
  • A method in a subclass should not throw the types of exceptions that the base method is not supposed to throw.

For more, check this article: https://www.baeldung.com/java-liskov-substitution-principle

Example

We have a class called Bird which contains two methods: Eat and Fly. We start writing code and create a Canary class and an Ostrich class that both inherit from Bird.

Bad Implementation

Let’s analyze this code, you will immediately notice that there is a problem. Ostriches cannot fly and yet they are birds too like Canari.

Two Questions:

Can the Bird be replaced by a Canary in all cases? ⇒ Yes

Can the Bird be replaced by an Ostrich in all cases? ⇒ No because of the fly method throwing an exception that the parent class Bird does not.

So Let’s correct this:

To solve this and implement the LSP, just create an intermediate class to differentiate this behavior.

We are therefore going to set up a class FlyingBird that will inherited by the Canary class.

The Ostrich class still inherit from Bird that contains now only the eat method.

Good Implementation

Conclusion

The LSP enables you to replace objects of a parent class with objects of a subclass without breaking the application.

Thank you for reading this quick post. If you like the content feel free to follow me on my social media profiles. Thank you.

Twitter: https://twitter.com/HBenkachoud
Linkedin: https://www.linkedin.com/in/hicham-benkachoud/

--

--