I believe the argument is as follows:
Let's say you have a method that takes a rectangle and adjusts its width:
public void SetWidth(Rectangle rect, int width) { rect.Width = width; }
It should be perfectly reasonable, considering what a rectangle is, to assume that this test passes:
Rectangle rect = new Rectangle(50, 20);
... because changing the width of the rectangle does not affect its height.
However, let's say you got a new square class from Rectangle. By definition, a square has a height and a width that are always equal. Try again:
Rectangle rect = new Square(20); // both width and height SetWidth(rect, 100); Assert.AreEqual(20, rect.Height);
This test will fail because setting the square width to 100 will also change its height.
Thus, the Liskov substitution principle is violated by deducing the square from the rectangle.
The "is-a" rule makes sense in the "real world" (a square is definitely a kind of rectangle), but not always in the software development world.
Edit
To answer your question, the correct design should probably be that Rectangle and Square are derived from the general class "Polygon" or "Shape", which does not apply any rules regarding width or height.
Matt Hamilton Jun 23 '09 at 3:54 2009-06-23 03:54
source share