The Liskov Substitution Principle states that every method of an object should also work correctly on any subclass of the object class. That is that inherited classes should respond to all of the parents methods.

So when creating a subclass we end up changing the parent class we should stop and think if classical inheritance is the appropriate solution. The suggested way of dealing with this problem is to use composition and delegation rather than inheritance. By the way, composition is to simply set an instance variable an object that has the behavior we are looking for, so we can use some of it’s method on our new class and not inherit the complete class. This way we complement our class with those methods.

Let’s see an example:

1
2
3
4
5
6
7
8
9
10
11
class Bird
  def hatch ...;  end
  def eat ...;  end
  def fly ...; end
end

class Ostrich < Bird
  def fly
    raise "Ostrich can't fly"
  end
end

There are many cases when we use inheritance when we really shouldn’t. The above case is obvious, but there are some other cases where the difference is subtle (The typical examples of Squares and Rectangles). Let’s see how can improve the above class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Bird
  def hatch ...;  end
  def eat ...;  end
  def fly ...; end
end

class Ostrich
  attr_accessor :bird
  def initialize
    @bird = Bird.new # => composition

  end

  def hatch ; bird.hatch ; end # => delegation

  def eat ;  bird.eat ; end # => delegation


end

This way we can still use the behavior from the bird class (duck typing) but without breaking the LSP.