first_page the funky knowledge base
personal notes from way, _way_ back and maybe today

SOLID: “The Liskov Substitution Principle—Agile Software Development Principles Patterns and Practices”

Liskov Substitution Principle

“What is wanted is something like the following substitution property: If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2, then S is a subtype of T. [Liskov88]“

Is it me, or is that painful to read? Robert Martin puts it a bit simpler:

Subtypes must be substitutable for their base types

The classic example of this principle in code is inheriting the Square Class from the Rectangle Class.

Classic Example of LSP

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 class Square: Rectangle { public override void SetWidth(int width) { _width = width; _height = width; }

public override void SetHeight(int height)
{
    _height = height;
    _width = height;
}

}

[TestFixture] public class RectangleTests { [Test] public void AreaOfRectangle() { Rectangle r = new Square();

    r.SetWidth(5);
    r.SetHeight(2);
    
    // Will Fail - r is a square and sets
    // width and height equal to each other.
    Assert.IsEqual(r.Width * r.Height,10);
}

}

If you look at the test above, it will fail because a square is being substituted for a rectangle and the area won't be 10 as expected. It will actually be 4 because “unexpectedly” in this case, both height and width are being set to each other when the width or height is set on a square. Therefore, if this behavior by Square is unacceptable and unexpected, Square should not be a subclass of Rectangle (at least not coded like this with these expectations anyway).

This is the whole point of the Liskov Substitution Principle. It basically wants you to think clearly about the expected behavior and expectations of a class before you derive new classes from it. It could turn out that when subclasses are substituted for a base class, you may get unexpected results. This is where unit tests can really be handy. The unit tests essentially describe and test for the expected behavior of objects (design by contract, if you will).

[http://codebetter.com/blogs/david.hayden/archive/2005/06/11/64477.aspx]

mod date: 2009-08-29T05:20:40.000Z