[see also <subtype>]
RESPONSE: pete@borland.com (Pete Becker), 23 Mar 93
class Square
{
public:
void SetHeight(int);
};
class Rectangle : public Square
{
public:
void SetWidth(int);
};
Which doesn't make a lot of sense, either. Because I haven't told you
what I want to do with these things.
Here's a better example:
class ScreenSquare
{
protected:
int Height;
public:
void SetHeight(int);
virtual void Draw();
};
class ScreenRectangle : public ScreenSquare
{
protected:
int Width;
public:
void SetWidth(int);
virtual void Draw();
};
While I like the abstract formulation in terms of invariants, it simply
doesn't apply here.
"Is-a" isn't a magic incantation. It's a guide to design,
but you still have to know where you're going.
RESPONSE: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller), 23 Mar 93
Yes. And not that in my terminology, the ScreenRectangle
given above, while a perfectly good class, is NOT a PURE subclass of
ScreenSquare because it adds extra state space in the form of
'Width'.
Its easy to see this: just delete the Draw and Set functions,
and what you have left is just composition:
struct S {
int Height;
};
struct R : public S {
int Height;
};
which is semantically equivalent to
struct R {
S h;
int Width;
};
However, the following IS pure subclassing, provided appropriate
comments as to the semantics are added:
class Sqr {
int Height;
public:
virtual void SetHeight(int h) {Height=h;}
virtual void SetWidth(int w) {Height = w;}
virtual void Draw()const;
};
class Rct : public virtual Sqr {
int Width;
public:
void SetWidth(int w) {Width=w;}
void Draw()const;
};
This allows independent control of the height and width of BOTH
a square and a rectangle. You need to add a comment perhaps
that says that you shouldnt assume that when you change the
height of a square the width remains unchanged.
In particular, although it is true that height == width for
a square, this MUST be just an implementation detail and MUST NOT
BE STATED AS A CONSTRAINT.
That is, there is a crucial difference between the properties
that Sqr happens to actually have, and those that it is
declared to have.
RESPONSE: krc@wam.umd.edu (Kevin R. Coombes), 23 Mar 93
...the last time this discussion went around, I argued the side that
insisted that a Square ISA Rectangle. Since that time, I've begun to
change my mind. It's true that a constant square ISA rectangle; the
problem arises when you're allowed to modify the objects...
RESPONSE: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller), 24 Mar 93
Its absurd to argue whether a square is
a rectangle or not without saying what a square and a rectangle ARE.
As far as I'm concerned, a square is a place where people
meet at fountains.
You have not changed your argument so much as your definition
of what a square/rectangle is.
If some transform exists:
t (R) -> R
and S < R (subset), then there is a map
t (S) -> R
that is, a member function 'Xscale' exists, but it cannot be
a mutator. A mutator must have the form:
t(X) -> X
or, more generally,
t(X, p1, p2, .... ) ->X
and the image t(S) of t|S (restriction) in R is not a subset of R.
The mathematics is elementary. What is hard to understand is that
whether something is a subclass of something else depends on
their respective definitions.
In particular, in C++, a rectangle with two equal sides IS NOT A SQUARE,
because in C++ two things have the same type if and only if they
are declared to have the same type.
RESPONSE: williamc@aifh.ed.ac.uk (William Chesters), 24 Mar 93
You're getting it the wrong way wround. The essence, if you like, of
a rectangle is that it is a polygon all of whose internal angles are
right angles. Certainly a square satisfies this defining property.
So a square isa rectangle. So the fact that it can't change its
width in proportion to its height shows that not all rectangles can,
ie, in general, rectangles can't.
RESPONSE: pete@borland.com (Pete Becker), 24 Mar 93
On the other hand, there's the old joke: how many legs does a dog have
if you call its tail a leg? Answer: four. Calling the tail a leg doesn't make
it one.
Similarly, asserting that there is only one true definition of a
rectangle, and that therefore a square must be a rectangle, doesn't make it
so. Especially if a consequence of applying that definition is that you have
to throw away useful properties of rectangles such as being able to change
their dimensions independently.
I can't imagine writing a window manager without being able to
independently resize the two dimensions of each screen rectangle. And I refuse
to go through some circumlocution to avoid calling them rectangles. They
clearly are rectangles.