Square and Rectangle

We consider the following class Rectangle.
We want to add a new class Square, and to avoid duplication, we want to re-use the class Rectangle.

Version 1

In mathematics, every square is a rectangle and it is quite a natural idea to apply this assertion to the classes Square and Rectangle :
In terms of object programming, this assertion may be translated into "Square extends Rectangle". Thus, we propose the following implementation of the class Square.
But this idea is wrong !

To prove it, we consider, for example in a class Rectangles, the following static method

public static void resize(Rectangle r, int factor) {
    r.setHeight(factor * r.height());
    r.setWidth(factor * r.width());

and, for example in a class Test, the following main method :

public static void main(String[] args) {
    Rectangle r = new Rectangle(10, 10);
    Square s = new Square(10);
    Rectangles.resize(r, 2);
    System.out.println("height = " + r.height() + " width = "
            + r.width());
    Rectangles.resize(s, 2);
    System.out.println("height = " + s.height() + " width = "
            + s.width());

The result of the command

> java Test

is the following :

height = 20 width = 20
height = 40 width = 40

while we were expecting

height = 20 width = 20
height = 20 width = 20

The reason is that the size (i.e. both height and width) of the square s is modified twice, once when calling setHeight, once when calling setWith in resize.

Version 2

In this version, we use inheritance again, but in such a way that there will be no direct relationship between Rectangle and Square.
To factorize code between Rectangle and Square, we use an abstract class : AbstractRectangle, but in such a way that this class cannot be used by the "client" of Rectangle and Square. For that, we introduce a package rectangle which will contain the three classes Rectangle, Square, AbstractRectangle. The Test class remains in the default package.

Note that the abstract class written to factorize the code could be public if you think that it may be reused by the client to write a new subclass. If not, it is better to  limit its visibility to its package.

Version 3

This version is the best, because it is simpler than the previous one. It is based on delegation. Concretely, it means that each instance of Square uses an instance of Rectangle to "do the job". This instance is called delegate in the implementation. The classes Rectangle and Test remain unchanged from the version 2.