From: krc@wam.umd.edu (Kevin R. Coombes)
Subject: Re: Const Inheritance
Organization: University of Maryland, College Park
Date: Fri, 6 Nov 1992 21:24:19 GMT

In article <Bx970t.B72@cdsmn.mn.org> wells@cdsmn.mn.org (Rich Wells) writes:
>Duane Voth (duanev@devnull.mpd.tandem.com) wrote:
>: frank@Cookie.secapl.com (Frank Adams) writes:
>: >The idea comes from one of the standard examples of an inheritance
>: >hierarchy: shapes.  Assume we have a class Shape, with a subclass
>: >Rectangle, and we want to add Square as a class.  It seems logical that
>: >Square should be a subclass of Rectangle.
>
>Let us not confuse "subset" with "subclass".  "Subclass" is a concept
>we use for implementation; it need not correspond directly to the
>"subset" and "superset" concepts we may be modeling.
>
>So: although the set of squares is a subset of the set of rectangles,
>it does not (necessarily) mean that the class "square" should be a
>subset of class "rectangle".  Inheritance can be used for both
>genericity AND specialization.  In this case, perhaps Square may be
>the immediate subclass of Shape, with Rectangle a more generic
>subclass of Square containing an extra field for the extra degree
>of freedom.
>
Standard dogma: public inheritance models an IS-A relationship.
Inheriting Square from Rectangle asserts that "a Rectangle is a Square",
so it can be used everywhere that a square is expected. This assertion
is clearly false. If I really need a Square, then just any old Rectangle
will not suffice. The reason, of course, was already mentioned:

>This leaves us with objects of type Square * which point
>to objects which violate the basic tenets of Squaredom, which is that
>all 4 sides are equal.  Therefore....
>
>: Perhaps the common mathematical definition of a square has led to
>: this delema.  Sounds as if, in this instance, there are more differences
>: between a square and a rectangle than there are similarities.
>: Would making class Square and class Rectangle peers of each other
>: cause so much duplication that the simplicity is unwaranted?
>
>No.  That is, Yes they may as well be peers.  The differences far
>outweigh the similarities.

I am not convinced by this last sentence. Most of the manipulations you
would need to carry out can be defined for rectangles: displaying them,
moving them, intersecting them, rotating them, etc. The code to implement
these operations could be written for rectangles without worrying about
whether or not the manipulated object was actually a square. The only
difference I see is that the lengths of the sides of the square are the
same, and this assertion does not necessarily hold true for rectangles.

I've just thought of another method to resolve some of the difficulty.
The essential problem seems to boil down to this

1. If you are working with a Rectangle, and change the Width, you do
not expect the Height to change as well.

2. If you are working with a Square, you must keep the Width and the
Height the same.

3. Consequently, the call ptr_to_rect->SetWidth(3) cannot satisfy both
properties 1 and 2 simultaneously (assuming a virtual function with
Rectnagle a base class for Square).

Perhaps SetWidth should return a new Rectangle instead of modifying
the old one? That is, if you try to change the Width of a Square, you
do not get the same Square back; instead, you get a new Rectangle with
the new width, but with height equal to the height of the square? You
could, of course, arrange things to allow the method to modify the
original object if it really is a rectangle to begin with.

Kevin Coombes <krc@math.umd.edu>