Skip to main content

Liskov substitution principle with simple example


Liskov Substitution Principle

Definition 2: Functions that use references to base classes must be able to use objects of derived classes without knowing it.

Definition 2: Object inheriting from base class or interface or other abstraction must be semantically substitutable for the original abstraction.

Definition 3: If a program module is using a Base Class, then the reference to the base class can be replaced with a derived class without affecting the functionality of the program module.

Problem

We all know that square is a rectangle from geometry. Now create a Rectangle base class with associated Height and Width properties and create Area() method to calculate the area in Rectangle base class.

    public class Rectangle
    {
        public virtual int Height { get; set; }

        public virtual int Width { get; set; }

        public int Area()
        {
            return Height * Width;
        }
    }

Now create a Square class derived from Rectangle base class.

    public class Square : Rectangle
    {
        public override int Height
        {
            get
            {
                return base.Height;
            }
            set
            {
                base.Height = value;
                base.Width = value;
            }
        }

        public override int Width
        {
            get
            {
                return base.Width;
            }
            set
            {
                base.Width = value;
                base.Height = value;
            }
        }
    }
Now create instance of a Rectangle class, set Height and Width as show below and call current instance Area() method to calculate the area.


Rectangle rectangle1 = new Rectangle();
rectangle1.Height = 5;
rectangle1.Width = 4;
Console.WriteLine(" Area of rectangle is " + rectangle1.Area());

The calculated area returned by “rectangle1” instance is 20. This is correct as since area of rectangle is 5 * 4 (Height * Width).

Now we know that Square is also a Rectangle. Create a square instance and assign it to Rectangle variable and set Height and Width as shown below.

Rectangle rectangle2 = new Square();
rectangle2.Height = 5;
rectangle2.Width = 4;
Console.WriteLine(" Area of rectangle is " + rectangle2.Area());

Now if we call Area() method from “rectangle2”, the returned area value is 16. But we are expecting 20 as 5 * 4 = 20.

This is not breaking any functionality but the above design is not giving the desired result. This kind of problem is known as violation of Liskov’s substitution principle.
The solution for this problem is to identify the suitable abstraction. If we fail do then we will end up with above mentioned violations.


Solution

Identify the proper abstraction. In this case we can create a new interface as IShape which contains only Area() method.

    public interface IShape
    {
        double Area();
    }

Now create a Rectangle and Square class derived from IShape interface.

    public class Rectangle : IShape
    {
        public int Height { get; set; }
        public int Width { get; set; }

        public double Area()
        {
            return Height * Width;
        }
    }

    public class Square : IShape
    {
        public int width { get; set; }

        public double Area()
        {
            return width * width;
        }
    }

Rectangle rectangle1 = new Rectangle();
rectangle1.Height = 5;
rectangle1.Width = 4;
Console.WriteLine(" Area of rectangle is " + rectangle1.Area());

The returned rectangle area is 20.

Square square = new Square();
square.Width = 4;
Console.WriteLine(" Area of rectangle is " + square.Area());

The returned square area is 16.

By using the same IShape interface we can extend this to calculate the area of Circle, Eclipse etc. by creating their respective classes and without modifying the existing code.

Comments

Popular posts from this blog

C# Generic Factory

Implement Factory pattern using generics     public interface IDoWork   {       string DoWork();   }     Declare an Interface first by abstracting the common  functionality    Here I am taking the example of DoWork     public class Manager : IDoWork   {     public string DoWork()     {         return "Manager Manages School" ;     }   }     Implement the IDoWork in concrete classes as shown      public class Teacher : IDoWork     {         public string DoWork()         {             return "Teacher teaches student in school" ;         }     }     public class Student : IDoWork     {         public string DoWork()         {             return "Study in school" ;         }     } This class will actually create an instance of the concrete class so that you can work on that        object further     public class FactoryDemo     {         public T Create

How to enable windows authentication in PostgreSQL

1.     Steps to create user or role in PostgreSQL ·         Open pgAdmin III ·         Login to PostgreSQL database ·         Select “Login Roles” and right click on mouse to view the context menu ·         Select “New Login Role” from context menu ·         Enter desired user name in “Role name” text box ·         Select “Definition” tab in “New Login Role” window ·         Enter desired Password in the given text box ·         Select “Role privileges” tab in “New Login Role” window ·         Select the privileges for the entered user or role ·         Select “SQL” tab in “New Login Role” window ·         This will display the auto generated script ·         Review the script and click on “OK” button ·         Now in the “Login Roles” the newly created role or user “newUser” is displayed ·         Now in pgAdmin III object browser select the database to which the newly created user should be ma

UML - Association, Aggregation, Composition, Generalization, Specialization, Realization and Dependency

Association Association is a simple relationship between two classes. For example A relationship between Professor Class and Student class is known as Association. Both Classes can exist without each other, so Professor and Student are two independent classes. In this kind of relationships there will not be any owner class. Both classes have their own life cycle. UML Notation:     Aggregation Aggregation is a special type of Association. It is known as “Has-A” relationship. For example A Department class can contain Professor Class. Here Department class is owner class. Here in this relationship even after deleting Department class, Professor Class can exits. UML Notation: Composition Composition is a special type of Aggregation. It is known as “Is-A” relationship. For example A University Class has many Department class. Here University and Department objects are dependent on each other. If we delete University cl