Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> If you have code that is set up to handle Rectangles, and you give that code a Square, then the code will handle the Square correctly.

Hmm...try setting different widths and heights on your square.



Many rectangle APIs, even in OO languages, are immutable, so setting width and length isn’t allowed anyways, all you can do is operate on it to get a new one.

I’ve rarely seen a square subtyped as a rectangle, let alone a mutable one. But I guess it’s possible if the mutable and immutable APIs are divided, so that squares are rectangles in its immutable sense but not in its mutable one.


This also pops up in modeling sets. You can define an immutable set by its explicit list of members (intrinsic) or by function that tests membership (extrinsic). If you want to have only one unified type Set that permits both methods of construction, it has to be invariant with respect to the type of its members. This is because the intrinsic approach is covariant (just as a list is) but the extrinsic approach is contravariant (just as a function is in its inputs).

I wish I had a really clear example of this, but it escapes me right now.


Try calculating the diagonal length of your rectangle, where that length is, by definition, 1.414 * width.

Alternatively, notice that if your definition of a "rectangle" includes the ability to arbitrarily modify its own width and/or height, then squares are not Liskov substitutable for rectangles and also aren't a kind of rectangle in the "meaning" sense given by definition 1 above.

Going by the Liskov criterion, a sentient rectangle can double its own width and still be a rectangle, but a sentient square cannot double its own width and still be a square.


On a square either setting the height immediately also sets the width to the same value OR all the types involved are immutable OR you have actively chosen to make a subtype that doesn't properly allow substitution, which is bad.

I think this really shows the point the author struggles with: It's not that OO is flawed because inheritance like this is somehow not possible. It's a paradigm that is deceptively easy but is really very hard to get right. You need to keep these things in mind all the time. The simplest thing to start with is just make everything immutable if you can afford it.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: