Wednesday, August 29, 2007

Liskov's Substitution Principle(LSP)


Motivation

There are situations when we design a program module and we create some class hierarchies. Then we extend some classes creating some derived classes.

When the new classes are used it assumed that they just extend without replacing the functionality of old classes. Otherwise the new classes can produce undesired effects when they are used in existing program modules. This is just a particularization of the Open Close Principle.

Likov's Substitution Principle states that 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.

Intent

Derived types must be completely substitutable for their base types.

Example

Below is the classic example for which the Likov's Substitution Principle is violated. In the example 2 classes are used: Rectangle and Square. Let's assume that the Rectangle object is used somewhere in the application. We extend the application and add the Square class. The square class is returned by a factory based on some conditions and we don't know the exact what type of object will be retuned. But we know it's a Rectangle. We get the rectangle object, set the width and height and get the area. But surprise!! This is not the expected result.

class Rectangle

{

protected int m_width;

protected int m_height;

public void setWidth(int width){

m_width = width;

}

public void setHeight(int height){

m_height = height;

}

public int getWidth(){

return m_width;

}

public int getHeight(){

return m_height;

}

public int getArea(){

return m_width * m_height;

}

}

class Square extends Rectangle

{

public void setWidth(int width){

m_width = width;

m_height = width;

}

public void setHeight(int height){

m_width = height;

m_height = height;

}

}

class LspTest

{

private static Rectangle getNewRectangle()

{

// it can be an object returned by some factory ...

return new Square();

}

public static void main (String args[])

{

Rectangle r = LspTest.getNewRectangle();

r.setWidth(5);

r.setHeight(10);

// user knows that r it's a rectangle. It assumes that he's able to set the width and height as for the base class

System.out.println(r.getArea());

// now he's surprised to see that the area is 100 instead of 50.

}

}

0 comments;Click here for request info on this topic:

Post a Comment