On Wed, Nov 5, 2008 at 1:51 PM, Pat Maddox <pergesu / gmail.com> wrote:
> Dean Wampler wrote:
>> On Wed, Nov 5, 2008 at 8:29 AM, Karl von Laudermann
>> <doodpants / mailinator.com> wrote:
>>> things in real life. For example, Rectangle should be a subclass of
>>> Square, not the other way around. This is because the Square class
>>> only needs one dimension member variable, e.g. "width", and the
>>> Rectangle subclass needs to add a second one, e.g. "height".
>>>
>>
>> Interesting idea. However, you have to be careful with this. Is a
>> Rectangle always substitutable for a Square? If you have mutable
>> states, then the following test will fail:
>>
> <snip> to make ruby-forum happy...
>> Clients of Square have a "contract" with the class that the height ==
>> width, which affects the area. Rectangle doesn't have this
>> restriction. Usually, we think of subclasses as "narrowing" the range
>> of allowed behaviors.
>>
>> I think it's great that you can nail down these details with
>> tests/specs!
>>
>> dean
>
> I think the answer is "it depends."  I would argue that the specs you
> gave are great for verifying that the implementation of Square works,
> but not so great at defining the contract.  The contract for calculating
> area may be a bit fuzzy to spec out, but I think you can be happy by
> saying that the area should be greater than one of the sides.  Now a
> Rectangle is substitutable for a Square.
>
> Pat

Right. That's why I said "clients of Square have a contract". It's an
interesting feature of Liskov substitution that it doesn't just
involve the types in isolation; it also involves users of the types.
There are certainly situations where the extra constraint on
"real-world" squares isn't an issue.


-- 
Dean Wampler
http://www.objectmentor.com
http://www.polyglotprogramming.com
http://www.aspectprogramming.com
http://aquarium.rubyforge.org
http://www.contract4j.org