Re: Clean Object Class Design -- Circle/Ellipse

From: Dmitry Kazakov <dmitry_at_elros.cbb-automation.de>
Date: Mon, 06 Aug 2001 08:19:39 GMT
Message-ID: <3b6e4d13.1936890_at_news.cis.dfn.de>


On Mon, 6 Aug 2001 09:43:22 +0300, "Cagdas Ozgenc" <co19_at_cornell.edu> wrote:

>> In "Type Inheritance: Is a Circle an Ellipse?" on www.dbdebunk.com
>> Date insists:
>> "As already indicated, it's my position that a circle categorically is
>> an ellipse in the real world -- to be specific, it's an ellipse in
>> which the two semiaxes coincide in the radius (equivalently, it's an
>> ellipse for which a=b). In my opinion, therefore, any "model" of
>> inheritance in which type CIRCLE is not considered to be a subtype of
>> type ELLIPSE can hardly be said to be a good model of reality."
>>
>> Is that a MAY (allow) or a MUST(require)?
>> Hint; what does *categorically* mean?
>
>The similar discussion was on "Is square a rectangle?" My conclusion was it
>totally depends on how you model the class hierarchy. For example if I model
>the Ellipse class like the following:
>
>class Ellipse {
>protected:
> float a;
> float b;
>public:
> /* pre: oldB = getAxisB();
> * post: newA == getAxisA() ; oldB() == getAxisB(); */
> void setAxisA(float newA) { a = newA; }
>
> /* pre: oldA = getAxisA();
> * post: newB == getAxisB() ; oldA() == getAxisA(); */
> void setAxisB(float newB) { b = newB; }
>
> float getAxisA() { return a; }
> float getAxisB() { return b; }
>}
>
>Now there is no way you can inherit Circle from this perfectly valid Ellpise
>class, because you cannot make the two axises equal to each other without
>violating the pre/post conditions stated by the base class. By definition of
>inheritance, the derived classes can only strengthen the post condition of
>the methods that they override.

This definition of inheritance is in fact a LSP definition of a constrained subtype. If you define subtypes as LSP-subtypes, then yes, you can design Ellipse, so that no Circle cannot be made its subtype.

>Hence a Circle derivation is not possible from the above Ellipse class.

LSP-conform derivation.

BTW your perfectly valid Ellipse is by no means perfect. What if setAxisA is called with the argument NaN? Will the result be an Ellipse? What if the argument is negative?

When the postconditions are allowed to be violated for "true ellipses", then it should be allowed for a circle as well. Let's consider contract violation as a property in LSP sense (:-))

Regards,
Dmitry Kazakov Received on Mon Aug 06 2001 - 10:19:39 CEST

Original text of this message