DEV Community

Fabrizio Bagalà
Fabrizio Bagalà

Posted on • Edited on

Liskov Substitution Principle

The Liskov Substitution Principle (LSP) states that:

Subtypes should be substitutable for their base types. This means that any instance of a subtype should be able to be used in place of its base type without affecting the correctness of the program.

In other words, if class S is a subclass of class T, then an object of class T should be able to be replaced with an object of class S without affecting the program's properties.

Violation of the principle

Consider the following example:

public class FlyingAnimal
{
    public virtual void Fly()
    {
        Console.WriteLine("I am a flying animal");
    }
}

public class Penguin : FlyingAnimal
{
    public override void Fly()
    {
        throw new NotSupportedException("Penguins cannot fly");
    }
}
Enter fullscreen mode Exit fullscreen mode

In this example, the Penguin class inherits from the FlyingAnimal class. However, since penguins cannot fly, the Fly method in the Penguin class throws an exception. This violates the LSP, as replacing an object of the FlyingAnimal class with an object of the Penguin class could cause runtime errors.

Application of the principle

To resolve the violation of the LSP, we can use the following design:

public abstract class Animal
{
    public virtual void Behavior()
    {
        Console.WriteLine("I am an animal");
    }
}

public class FlyingAnimal : Animal
{
    public override void Behavior()
    {
        base.Behavior();
        Console.WriteLine("and I can fly");
    }
}

public class Penguin : Animal
{
    public override void Behavior()
    {
        base.Behavior();
        Console.WriteLine("but I cannot fly");
    }
}
Enter fullscreen mode Exit fullscreen mode

In this example, we have introduced an abstract class Animal and two derived classes: FlyingAnimal and Penguin. The Animal class has a Behavior method that describes the basic properties of an animal. The derived classes extend the Behavior method to describe additional specific properties for each type of animal. In this way, we can replace an object of the Animal class with an object of its subclasses without affecting the program's properties.

Conclusion

In this article, we have discussed the Liskov Substitution Principle, which teaches us to develop derived classes that can seamlessly replace their base classes without compromising the correctness of the program. This is achieved by using proper inheritance hierarchies and polymorphism, ensuring that derived classes adhere to the contracts set by their base classes. Consequently, this principal aids in creating code that is more maintainable and extensible, as it minimizes unexpected behavior when using derived classes in place of their base classes.

References

Top comments (0)