What's wrong with the Square and Rectangle inheritance?-Collection of common programming errors

Consider the abstract base class or interface (whether something is an interface or abstract class is an implementation detail rather irrelevant to the LSP) ReadableRectangle; it has read-only properties Width and Height. It would be possible to derive from that a type ReadableSquare, which has the same properties but contractually guarantees that Width and Height will always be equal.

From ReadableRectangle, one could define concrete type ImmutableRectangle (which takes a height and width in its constructor, and guarantees that the Height and Width properties will always return the same values), and MutableRectangle. One could also define concrete type MutableRectangle, which allows the height and width to be set at any time.

On the “square” side of things, an ImmutableSquare should be substitutable for both an ImmutableRectangle and a ReadableSquare. A MutableSquare, however, is only substitutable for a ReadableSquare [which is in turn substitutable for a ReadableRectangle.] Further, while the behavior of an ImmutableSquare is substitutable for an ImmutableRectangle, the value gained by inheriting a concrete ImmutableRectangle type would be limited. If ImmutableRectangle were an abstract type or interface, the ImmutableSquare class would only need to use one field rather than two to hold its dimensions (for a class with two fields, saving one is no big deal, but it’s not hard to imagine classes with a lot more fields, where the savings could be significant). If, however, ImmutableRectangle is a concrete type, then any derived type would have to have all the fields of its base.

Some types of square are substitutable for the corresponding types of rectangles, but a mutable square is not substitutable for a mutable rectangle.