On Wed, Nov 5, 2008 at 8:29 AM, Karl von Laudermann
<doodpants / mailinator.com> wrote:
> On Nov 4, 5:45 pm, Mike Lopke <reglo... / cableone.net> wrote:
>> For example, the typical Liskov Substitution example you see in Java has
>> the case where you have a Rectangle class and a derived Square class.
>> The Rectangle has an independent width and height. They have to be the
>> same for the Square.
>
> One guiding principle when designing a class heirarchy is that the
> class with fewer data members should be the superclass, and the class
> with more data members should be the subclass. This sometimes leads to
> cases which are counterintuitive with respect to the way we think of
> 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:

class Square
  attr_accessor :height
  def initialize height
    @height = height
  end
  def area
    height * height
  end
end
class Rectangle < Square
  attr_accessor :width
  def initialize height, width
    super(height)
    @width = width
  end
  def area   # this override is where the trouble starts...
    height * width
  end
end

require 'rubygems'
require 'spec'

describe Square, "height vs. width" do
  it "should keep the height and width equal" do
    [Square.new(2), Rectangle.new(2,2)].each do |s|
      p s.inspect
      s.height = 4
      s.area.should == 16   # fails for Rectangle
    end
  end
end

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
-- 
Dean Wampler
http://www.objectmentor.com
http://www.polyglotprogramming.com
http://www.aspectprogramming.com
http://aquarium.rubyforge.org
http://www.contract4j.org