## Modelling with Classes: Square and Rectangle revisited

Classic problem in class-modelling: how to express that a square is a special kind of rectangle?  Practically the best approach is in general to refrain from subclassing and add a boolean method isSquare() to the rectangle class instead.

In order to deepen understanding, let us scrutinize the situation a bit closer here, using logical/ structural foundations of modelling:  Undoubtedly, Square is a subclass of Rectangle, since all squares constitute a proper subset of all rectangles. This could be simply describes as:

(R1) Rectangle: real a, real b, {a>0}, {b>0}
(S1) Square: real a, {a>0}
A method area() would look like: a * b in Rectangle and a² in Square.

However, additionally we have the challenge of inheritance, that is, we want to obtain the description of Square by just extending the description of Rectangle. This is not satisfied by the solution above, since Square drops the b. Notice, that we talk about just the description of the classes here. Their extensions (rectangles and squares) remain unaffected. Of course, one could specify it like this:

(S2) Square: real a, real b, {a>0}, {a=b}
But here b is redundant and e.g. area() could be a * b or a² arbitrarily.

Thus, for a subclass Square we can choose to drop inheritance or accept redundancy. Now, inheritance is a very desirable feature.  For example, it allows the area() method of (S2) to remain unchanged in the Square class.  Just imagine, how confusing developing would become, when subclasses exhibit methods of superclasses differently structured or named.

This is why it’s recommendable to accept redundancy for the benefits of inheritance here. To implement this either by a subclass Square, as in (S2), or inside the Rectangle class, as with an isSquare() method, is left to practical considerations.

So long
|=