TITLE: Square wars, or, just when you thought it was safe to use rectangles... [see also ] 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.