If a Square is a type of Rectangle, than why can't a Square inherit from a Rectangle? Or why is it a bad design?
I have heard people say:
If you made Square derive from Rectangle, then a Square should be usable anywhere you expect a rectangle
What is the problem here? And why would Square be usable anywhere you expect a rectangle? It would only be usable if we create the Square object, and if we override the SetWidth and SetHeight methods for Square than why would there be any issue?
If you had SetWidth and SetHeight methods on your Rectangle base class and if your Rectangle reference pointed to a Square, then SetWidth and SetHeight don't make sense because setting one would change the other to match it. In this case Square fails the Liskov Substitution Test with Rectangle and the abstraction of having Square inherit from Rectangle is a bad one.
Can someone explain the above arguments? Again, if we over-ride SetWidth and SetHeight methods in Square, wouldn't it resolve this issue?
I have also heard/read:
The real issue is that we are not modeling rectangles, but rather "reshapable rectangles" i.e., rectangles whose width or height can be modified after creation (and we still consider it to be the same object). If we look at the rectangle class in this way, it is clear that a square is not a "reshapable rectangle", because a square cannot be reshaped and still be a square (in general). Mathematically, we don't see the problem because mutability doesn't even make sense in a mathematical context
Here I believe "re-sizeable" is the correct term. Rectangles are "re-sizeable" and so are squares. Am I missing something in the above argument? A square can be re-sized like any rectangle.