Re: Why is OO Popular?

From: Alfredo Novoa (alfredo_at_ncs.es)
Date: 05/03/04


Date: 2 May 2004 16:36:41 -0700

stevenwurster@lycos.com (Steven Wurster) wrote in message news:<d853834.0405011747.7816184d@posting.google.com>...
> alfredo@ncs.es (Alfredo Novoa) wrote in message news:<4092e989.4349984@news.wanadoo.es>...
> >
> > >And an OO ellipse is not a circle.
> >
> > In the typical OO designs it is, and squares are not rectangles.
>
> In a lot of the "stereotypical" examples you'll see for OO designs,
> ellipses are circles and squares are rectangles.

Ellipses are circles is horribly wrong and squares are rectangles is
correct, but it is contrary to the stereotypical examples.

> Unfortunately, these
> designs are wrong (based on breakage of the LSP, see below).

Circles are ellipses breaks LSP
Circles are ellipses
--------------------------------
LSP is broken QED

> And to
> make matters worse, it seems that these examples are given by people
> who don't seem to know what the LSP is

LSP is only a wrong principle.

> We'll use the square/rectangle example. If square inherits from
> rectangle, then we know the standard problem that the sides of a
> rectangle can be changed independently

Like most OO practicioners you are confusing values and variables all
the time.

Rectangles are values and values are immutable, but you can place a
square value in a rectangle variable or a square value in a square
variable.

If you have a square value in a rectangle variable then you can
replace the square value by a rectangle value, but you are not
changing the sides of the square, you are replacing a value for
another value.

var r: rectangle;
r := square(5); // there is a square value in r
r.height := 10; // there is a rectangle value in r
if r is square then
  WriteLn('OO is mad');

r.height := 10; // is only a shorthand for r := rectangle(10,
r.width);

>, but that's not true for a
> square. Because of that, a square cannot be treated like a rectangle
> by clients

You are confusing values and variables. A square value can be treated
like a rectangle value because it is a rectangle value, but a square
variable can not be treated as a rectangle variable because the square
variable is more restricted.

There are two kinds of substitutability: value substitutability and
variable substitutability. Something forgotten by the LSP.

>, who only know the interface provided by rectangle, and
> think they are getting a rectangle when they are actually getting a
> sqaure at run-time (which is fine when the LSP is upheld).

They think they are getting a rectangle and they are getting a
rectangle. Squares ARE rectangles. Squares have rect angles.

> Looking at these side-setting routines for rectangle, we see that
> their contracts tell us that when we attempt to change the length of a
> side, the change is successful, and the new length is what we
> requested. But square breaks that by (most likely) setting the other
> side equal to the new one that we just changed. But this breaks the
> contract, because clients of rectangle aren't expecting that other
> side to change.

If the client of rectangle receive a rectangle that is also a square
and he changes only one side then he will have a rectangle that is not
a square. No problem here.

var r: rectangle;
r := rectangle(5, 5);
if not (r is square) then
  WriteLn('OO is mad')
r.height := 10;
if not (r is square) then
  WriteLn('Correct');

> So, this kind of inheritance breaks the LSP, which of
> course says that descendant classes must be able to pass for
> ancestors.

That's why LSP is a broken principle.

> > Subtyping is only math. OO does not match with math thus what OO does
> > is not subtyping.
>
> OO does not claim to match math.

Then it should not claim to match the real world.

> Calling a descendant class a subtype
> is misleading.

I completely agree. Subclasing is related to delegation and not to
subtyping.

> In fact, in a large number of cases, descendants might
> be considered supertypes, as they tend to add features.

And it is contrary to the reality. OO subclasing is not good for
modeling the real world.

> In reality,
> descendants are simply specializations of their ancestors, not
> subtypes.

A rectangle is a generalization of a square and not a specialization.

Square is a specialization of rectangle.

With a good language it could be defined as:

type square is rectangle where height = width;

> Many people, especially those who teach OO incorrectly (as
> mentioned above), make this mistake. Descendants are not expected to
> cover "less" cases, as doing so breaks the LSP.

But if you teach correctly something that is incorrect, the situation
is not a lot better.

Regards
  Alfredo



Relevant Pages

  • Re: Agile Ecosystems Vs (Rational) Unified Process
    ... > conflict between Rectangle and Square, and not one line of code ... and practice on the other are seen as mostly independent and separate ... Google Home - Advertising Programs - Business Solutions - About Google ...
    (comp.object)
  • Re: SubTyping versus SubClassing
    ... small subset of ones used in mathematics. ... >> which you'd better have a square for each rectangle, ... Operations defined on the types are that theorems we have to prove ...
    (comp.object)
  • Re: delegation vs. inheritance
    ... The real problem was that Square was defined with a sideLength knowledge attribute while Rectangle was defined with majorSideLength and minorSideLength -- apples & oranges. ... The difference lies in whether LSP is an issue; if one also needs a definition that is consistent with Rectangle, then only the first abstraction of the geometric properties works. ...
    (comp.object)
  • Re: Frage zu verdecktem Member
    ... definieren und zwar in dem man sagt, die Menge der Quadrate ist die Menge aller Rechtecke für die gilt, dass beide Seiten gleich lang sind. ... In Java ist ein Rectangle auch dann ein Rectangle wenn beide Seiten gleich lang sind und kann nicht ein Square werden, weil das Typsystem es nicht erlaubt. ...
    (de.comp.lang.java)
  • Re: delegation vs. inheritance
    ... the debate centered around deriving Rectangle behaviors from Square behaviors. ... The real problem was that Square was defined with a sideLength knowledge attribute while Rectangle was defined with majorSideLength and minorSideLength -- apples & oranges. ... So if one defined sideLengthN for Square, then Rectangle could be a subclass without any LSP inconsistency in the knowledge attributes. ...
    (comp.object)

Loading