# Liskov Substitution Principle (SOLID 3/6)

## Definition

Liskov substitution principle (LSP) has the most difficult definition of five SOLID principles. Especially if we look at the original definition which is practically mathematics:

Subtype Requirement: Let φ(x) be a property provable about objects x of type T. Then φ(y) should be true for objects y of type where is a subtype of T. (Barbara Liskov)

That is something I can’t figure out, especially that it has something to do with object-oriented programming. Robert C. Martin has modified it to a more user-friendly version:

Derived classes must be substitutable for their base classes. (Robert C. Martin)

But this doesn’t either make any sense of what LSP really is. Luckily LSP is much easier in practice. I will start by violating LSP because that is easier than to start by explaining what it is.

## Example: Violating LSP

Consider we have an `IBird` interface with a `Fly` method:

```public interface IBird
{
void Fly();
}
```

But when we try to code a `Penguin` class, we can’t implement the `Fly` method:

```public class Penguin : IBird
{
public void Fly()
{
throw new NotSupportedException("Penguins can't fly");
}
}
```

This is a quite typical violation of LSP. This was a really simple example but think if we have a good class and we want to extend its behavior. We inherit it (like `Penguin` above) and code something more. But then we realize that something that we inherited doesn’t fit anymore and we throw `NotSupportedException`.

LSP is often violated by attempts to remove features. (Mark Seemann)

(This example is based on Tom Dalling’s blog post about LSP and Mark Seemann’s Pluralsight course about SOLID principles.)

## Easier Definition

LSP defines that objects of a superclass shall be replaceable with objects of its subclasses without breaking the application. (Thorben Janssen)

Now if we look at the `IBird` and `Penguin` example again with this more reasonable definition, we will understand what LSP is. I will explain how the example violated this.

If we have the following method:

```public void LetThemFlyAway(IBird[] birds)
{
foreach (var bird in birds)
bird.Fly();
}
```

And we have a `Penguin` object in birds array it will throw a `NotSupportedException`. `Penguin` object, which is the subclass of `IBird`, will break the application. If `IBird` and `Penguin` were coded according to LSP it wouldn’t throw an exception.

Practically what LSP says is that if we use superclass in our code, we should be able to replace it with its subclass, an application will still run successfully.

LSP requires the objects of your subclasses to behave in the same way as the objects of your superclass. (Thorben Janssen)

## Desing by Contract, and We Will Follow LSP

If it feels difficult to write code that follows LSP, try to follow design by contract. In brief (and little simplified) design by contract means that methods have:

• Preconditions for input parameters and
• postconditions for output parameters.

For input parameters, this means that subclass has to accept the same input parameters in the overridden method as superclass accepts in its method. We can make validation looser in subclasses but we are not allowed to make it more strict. It would violate LSP like previous `Penguin` example and throw an exception if some subclass won’t accept some input that superclass accepts.

We should think output parameters as a return value. The rule is basically the same as with the inputs: the return value of subclass’ method should follow the same rules as the return value of superclass’ method. Unlike with inputs we are not allowed to loosen the rules with outputs. But we can make them more strict if we want. Loosening output requirements also would violate LSP. Think that we have a superclass with the following method:

```public class MySuperClass
{
public virtual int GetValue()
{
var random = new Random();
return random.Next(1, 10);    // returns 1...9
}
}
```

And then we have a method that uses it to get the sum of numbers:

```public int CalculateSumOfValues(MySuperClass[] myClasses)
{
int sum = 0;
foreach (var myClass in myClasses)
sum += myClass.GetValue();
return sum;
}
```

Remember that `MySuperClass` expects that return value of `GetValue` method is between 1 and 9. With three input objects, the return value of `CalculateSumOfValues` method should be a value between 3 and 27. This is the postcondition contract of the `CalculateSumOfValues` method. If we now create a subclass that violates design by contract and loosens return value:

```public class MySubClass : MySuperClass
{
public override int GetValue()
{
var random = new Random();
// Returns 0...9 even if design by contract says should return 1..9.
return random.Next(0, 10);
}
}
```

Now if we call `CalculateSumOfValues` method with three `MySubClass` objects, it will return a value between 0 and 27. That breaks the postcondition contract of the `CalculateSumOfValues` method which says that the return value should be between 3 and 27. And we have also violated LSP! So if we follow design by contract, we can’t loosen postcondition requirements.

But vice versa we can make return values more strict. For example, if we change `MySubClass`‘s `GetValue` method to return a value between 2 and 8 it wouldn’t be a problem. Because then `CalculateSumOfValues` would return a value between 6 and 24 and that fits into return value’s requirement to be between 3 and 27.

If we follow these two rules when overriding methods in a subclass, our code probably follows LSP.

## Relationship With the Open/Closed Principle

While writing this blog post I have been thinking that isn’t LSP practically same as the open/closed principle (OCP)? My opinion is that they are quite similar but they underline different things. OCP is more about extending classes and LSP is more about using objects. If you want to read a deep analysis why LSP and OCP are not same I suggest you read this question in Software Engineering StackExchange.

## What Makes LSP Important?

At first glance, LSP seems little difficult and unpractical. The definition isn’t easy to understand. And even if we see code example it is still not easy to understand. It needs some time to understand it.

How can it be so important that it has its own letter in SOLID principles? The reason is that it makes it more easy to use objects because we can trust that they behave as they should. If our code follows LSP, we can change to use any subclass of the given superclass and be sure that our code still works as it is supposed to. This is because of LSP guarantees that every object of subclasses behaves just like superclass.