Liskov Substitution Principle.. attempted

In Friday’s post, I explained and gave examples of SOLID principles. I left out an example of the Liskov Substitution Principle because it deserves its own post. Here’s a recap of the relevant section:

In short, the idea is that objects in a given class hierarchy should be replaceable with their subtypes without modifying the “correctness” of the system. In proper terms, it means that method/class preconditions cannot be strengthened, post conditions can’t be weakened, all exceptions thrown must equally interchangeable, and method signatures should be completely compatible.

So the Liskov Substitution Principle boils down to:

  1. method/class preconditions cannot be strengthened;
  2. method/class post conditions can’t be weakened;
  3. all exceptions thrown must equally interchangeable; and
  4. method signatures should be completely compatible.

When we actually try to apply this to the real world, it gets complicated. So to begin, we’ll start with one of the first examples many of us saw when we learned about Object Orientation.. Shapes!

To get rolling, here’s a simple Rectangle class:

It doesn’t do anything special but definitely supports the definition of a Rectangle. Next, let’s implement a Square class. Since we know that “all squares are rectangles but not all rectangles are squares,” it implies this class hierarchy:

Unfortunately, we have different method signatures, so we’ve broken requirement 4. So let’s fix that:

But now we might end up with an un-square Square, so we need to validate the sides:

But now we’ve added a new exception and added new preconditions on the input.. breaking requirements 1 and 3.

Unless I’m missing something, LSP is difficult to implement “properly” even with simple class structures. Granted, this is a bit of a contrived example, but it’s the first OO example in most classes, books, and even OO articles out there. Imagine if I had started with the other Shapes example and included a circle or triangle?

If we can’t practice “good” OO Design principles here with less than 20 lines of code, how can we do it in the real world? Is it even reasonable to expect it?

Of course, I might be wrong.. please tell me how. I’d love the insight.

About Keith Casey

This should be something about myself. I've had suggestions that it should be "useful information" but I'm not sure about that.