Composition over Inheritance

In object oriented design, inheritance can be a good thing. It has many uses and, in particular, it is almost essential for certain design patterns.

However, inheritance can also be a bad thing. Get it wrong, and your code can end up in a mess. So, we say, as a general rule, prefer composition over inheritance. But what does that mean?

Before answering that, let's define when it is appropriate to consider inheritance.

One of the common heuristics is the is a? and has a? rule. With this heuristic, we only consider inheritance if the is a? rule is applicable. For example, if we are considering whether Van should inherit Vehicle, we might say 'a van is a vehicle' and be satisfied. But what if our domain has no need for Vehicle and instead we're using Van as a specialized container for moving stock? Should Van inherit StockContainer? Let's apply the heuristic: 'a van is a stock container'. That seems to be OK. However, there is a problem. Let's try the has a? heuristic: 'a van has a stock container'. Hmm, that sort of makes sense too if you consider the storage compartment separately. The problem is that our spoken language is heavily nuanced and is not always reliable when used to design software.

When we say 'is a' in the test above, what we should really mean 'is always and never not a'; and when we say 'has a', we should mean 'has, or has the behaviour of, a'. Let's try that out:

  • A van is always and never not a vehicle. That seems reasonable.
  • A van is always and never not a stock container. That does not sound right.
  • A van has, or has the behaviour of, a stock container. That's better.

So we might consider Van inheriting Vehicle, but we certainly should not consider Van inheriting StockContainer; and use composition here instead.

But, sometimes, it's even more subtle than that. Consider the following statements:

  • Barney is a dog.
  • Barney is a labrador.
  • A dog in an animal.
  • Labrador is a breed.


  • Barney is an animal.
  • Barney is a breed.

Clearly, the last statement is incorrect. 'Barney' is not a breed. The above example provides us with another heuristic, which is to try walking further up the inheritance chain.

If we hadn't taken this step, we may have modeled the above using inheritance and ended up with the following:

class Animal

class Dog < Animal

class Labrador < Dog

barney =  

And we would probably end up regretting it. So what does 'Labrador is a breed' tell us about how to design our objects?

It suggests that the attributes associated with breed should be factored out into a separate class:

class Breed  
  attr_accessor :size

  def name

  def colours

  def traits

class Labrador < Breed  
  NAME = 'Labrador'

  def name

  def colours
    [:gold, :chocolate, :black]

  def traits

And we can then use composition to share these with Dog:

barney =  

Or perhaps with a factory method:

barney = Dog.create(:labrador)  

We might then access these through a breed getter method:  

In a strongly typed language such as Java or C#, we can further improve this by defining these behaviours on an interface, e.g. IBreed, implement that interface in Dog as well and delegate it to Labrador.

If we are using a loosely-typed language such as Ruby, then we might add some of the Breed methods to Dog and delegate these to Labrador.