11,705,119 members (42,041 online)

# Understand Liskov Substitution Principle (LSP)

, 20 May 2013 CPOL 35.7K 35
 Rate this:

## Introduction

Here I am going to discuss the Liskov’s Substitution Principle of S`O`LID . Now what does SOLID means ? SOLID is object oriented design principle , Where each letter has it own meaning

• S-> Single responsibility
• O-> Open Closed
• L-> Liskov substitution
• I-> Interface segregation
• D-> Dependency inversion

According to Wikipedia the definition of SOLID is

" `SOLID `are guidelines that can be applied while working on software to remove code smells by causing the programmer to refactor the software's source code until it is both legible and extensible.

## Background

If you read my previous article it will be very helpful  for you to
understand SOLD .

## Using the code

Before start technical discussion i want to answer the below questions :

What is Liskov substitution principle ?
Answer: "objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program"

Is my answer is tough to understand ?  Ok making it more easy

"it means that we must make sure that new derived classes are extending the base classes without changing their behavior"

Let's consider an example to make it better understand. If you read articles related Liskov principle one example  is very popular . Yes that is Rectangular and Square. Here i will show you the same but will try to explain each and every aspect clearly.  Before start technical discussion look at the below picture and answer the questions.

`Fig : 1`

Question : Square is a Rectangle ?

If you remember Inheritance then the word "Is a" relationship familiar to you . So if i convert this to code it looks like the following
```public class Rectangle
{
protected int _width;
protected int _height;
public int Width
{
get { return _width; }
}
public int Height
{
get { return _height; }
}

public virtual void SetWidth(int width)
{
_width = width;
}
public virtual void SetHeight(int height)
{
_height = height;
}
public int getArea()
{
return _width * _height;
}
}

public class Square : Rectangle  // In an "is a" relationship, the derived class is clearly a
//kind of the base class
{
public override void SetWidth(int width)
{
_width = width;
_height = width;
}

public override void SetHeight(int height)
{
_height = height;
_width = height;
}
}
```
So for every thing is ok .Now we will calculate the area of the Fig:1 `Rectangle `and `Square`.

```public void AreaOfRectangle()
{
Rectangle r = RectangleFactory(); // Returns the rectangle type object
r.SetWidth(7);
r.SetHeight(3);
r.getArea();
}
```
So can you tell me the out put of the  `r.getArea()`; method . Yes very simple the expected output is

7 * 3=21 . Ok now run the program with the below `RectangleFactory()` method and see did we get our expected result or not ?
```public  Rectangle RectangleFactory()
{
return new Square();
}
```
One thing i want to mention about the  `RectangleFactory``()` is that , this method is now exposed to you. But think as if you are getting the `Rectangle `object just by using a factory dll or from any service where you have no idea what type of rectangle object will be return.

Did you see the result? Yes its

This is the out put

``` 9
```

So Whats wrong there ? Remember as i said earlier

"we must make sure that new derived classes are extending the base classes without changing their behavior"
if we say specifically

"we must make sure that Square classes are extending the Rectangle without changing their behavior"

Is the above sentence correct according to our program?

No, the problem is

`without changing their behavior `

but we change the behavior of the base `Rectangle `class. Did you notice how ? No , Ok Lets see
```public override void SetWidth(int width)
{
_width = width;
_height = width; //Change the behavior here by assigning the width to Rectangle _height

}

public override void SetHeight(int height)
{
_height = height;
_width = height;//Change the behviour here by assigning the height to Rectangle _width

}
```

Width=Height is `must be rule` for  `Square not for ` `Rectangle `.So when `Square `object returns from `Rectanglefactory() `before calling `getAraa()` user assigns `r.SetHeight(3) and ``r.SetWidth(7)` and waiting for a result 21 but getting 9`It `changes the  result. But the end user was expecting the result of `Rectangle `area.

So violation of Liskov substitution principle occurs.

Now the solution is to manage the class inheritance hierarchies correctly. Lets introduce another class

```public class Quadrilaterals
{
public virtual int Height { get; set; }
public virtual int Width { get; set; }
public int getArea()
{
return Height * Width;
}
}
```

Now change the inheritance hierarchies  by making it base class.

```public class Rectangle :Quadrilaterals
{

public override int Width
{
get { return base.Width; }
set { base.Width = value; }
}
public override int Height
{
get { return base.Height; }
set { base.Height = value; }
}

} ```

``` public class Square : Quadrilaterals  // In an "is a" relationship, the derived class is clearly a
//kind of the base class
{
public override int Height
{
get { return base.Height; }
set { SetWidthAndHeight(value); }
}

public override int Width
{
get { return base.Width; }
set { SetWidthAndHeight(value); }
}

private void SetWidthAndHeight(int value)
{
base.Height = value;
base.Width = value;
}
} ```

Now our factory method also changes .

```public Quadrilaterals QuadrilateralsFactory()
{
return new Square();
}
{
r.Height=7;
r.Width=3;
r.getArea();
}
```

## Points of Interest

So from users point of view now s/he expecting the area of `Quadrilateral `not the `Rectangle `.By using this input  when output comes 21 is a `Rectangle `area and when 9 its a `Square `

```Quadrilaterals r = new Rectangle();
r.Height=7;
r.Width=3;
r.getArea();

r.Height = 7;
r.Width = 3;
r.getArea();
```

Now user getting the expected behavior from the program. So Satisfy Liskov Substitute  Principle (LSP)

## Share

I am a Sr.Software Engineer at Brain Station -23. I have 5+ years of work experience in .Net technology. I strongly believe that before software can be reusable it first has to be usable.

My contact info :

mfrony2003@yahoo.com
mfrony2003@hotmail.com

## You may also be interested in...

 First Prev Next
 My vote of 5 Humayun Kabir Mamun1-May-15 0:00 Humayun Kabir Mamun 1-May-15 0:00
 Nicely explained! Shahdat Hosain10-Nov-13 13:01 Shahdat Hosain 10-Nov-13 13:01
 My vote of 3 Silvabolt16-Oct-13 3:58 Silvabolt 16-Oct-13 3:58
 Explaining LSP by sacrificing POLA principle. Ryszard Dżegan8-Sep-13 22:59 Ryszard Dżegan 8-Sep-13 22:59
 Re: Explaining LSP by sacrificing POLA principle. VikasChaturvedi11-Jun-14 21:43 VikasChaturvedi 11-Jun-14 21:43
 My vote of 5 Mohammed Hameed22-May-13 19:17 Mohammed Hameed 22-May-13 19:17
 I see where you are going but... MarkRHolbrook22-May-13 8:38 MarkRHolbrook 22-May-13 8:38
 Not a good example of Liskov cjcordova22-May-13 7:51 cjcordova 22-May-13 7:51
 My vote of 3 Paulo Zemek21-May-13 10:23 Paulo Zemek 21-May-13 10:23
 This is wrong. Paulo Zemek21-May-13 8:58 Paulo Zemek 21-May-13 8:58
 Re: This is wrong. Faisal(mfrony)21-May-13 14:28 Faisal(mfrony) 21-May-13 14:28
 Re: This is wrong. Paulo Zemek21-May-13 15:17 Paulo Zemek 21-May-13 15:17
 Re: This is wrong. Faisal(mfrony)21-May-13 15:30 Faisal(mfrony) 21-May-13 15:30
 Re: This is wrong. Faisal(mfrony)21-May-13 15:20 Faisal(mfrony) 21-May-13 15:20
 Explained here RaviBattula21-May-13 0:02 RaviBattula 21-May-13 0:02
 Last Visit: 31-Dec-99 18:00     Last Update: 29-Aug-15 0:12 Refresh 1

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Web02 | 2.8.150819.1 | Last Updated 21 May 2013