class Rectangle attr_accessor :width, :height, :top_left_corner def new(width,height,top_left) ... ; end def area ... ; end def perimeter ... ; end end # A square is just a special case of rectangle...right? class Square < Rectangle # ooops...a square has to have width and height equal attr_reader :width, :height, :side def width=(w) ; @width = @height = w ; end def height=(w) ; @width = @height = w ; end def side=(w) ; @width = @height = w ; end end # But is a Square really a kind of Rectangle? def make_twice_as_wide_as_high(r, dim) r.width = 2*dim r.height = dim end # violates LSP, if this method is part of "contract"! # LSP-compliant solution: replace inheritance with delegation # Ruby's duck typing still lets you use a square in most places where # rectangle would be used - but no longer a subclass in LSP sense. class Square def initialize(side,top_left_corner) @rect = Rectangle.new(side,side,top_left_corner) end def area ; @rect.area ; end def perimeter ; @rect.perimeter ; end def side=(s) ; @rect.width = @rect.height = s ; end end