For the past few weeks I have been doing a chapter-by-chapter review of Agile Software Development Principles, Patterns, and Practices by Robert Martin. So far, it has covered a lot of good introductory information on various Agile Methodologies (Test-Driven Development, Refactoring, Pair Programming, Project Planning, Extreme Programming, etc.) as well as talked about various object-oriented programming principles, which is what I am still covering now.
Here is a chapter-by-chapter breakdown on what I have covered so far:
Chapter 10 is on the Liskov Substitution Principle:
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.
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).
If you want to read some discussions as to the usefulness of this principle, whether it should be a principle, and thoughts on the classic example above, check out this wiki. You can also read what Robert Martin has to say about it from this PDF.