The 4th principle from the red grade in the clean code development grade system says (from wikipedia):
Composition over inheritance (or Composite Reuse Principle) in object-oriented programming is a technique by which classes may achieve polymorphic behaviour and code reuse by containing other classes that implement the desired functionality instead of through inheritance.
Inheritance is used in object-oriented programming as a way to reuse code through different objects. We can define parent-children object structures, so methods an variables are passed from the parents to their children – the code is inherited. This is a powerful mechanism to avoid code replication – to be DRY-, but it has its drawbacks.
The problem is that in a parent-children structure, children are dependent of their parent. If a behaviour in a parent changes all its children’s behaviours will automatically change. Or if a new behaviour is added to the parent all the children will inherit that behaviour too. Sometimes this is not what we really want. Let’s see why.
I am going to use an example from the first chapter of the book head first design patterns.
In the example, the user wants to build an application which deals with different types of ducks. Every duck flies, swims, and quacks, so in order to reuse those behaviours a Duck super-type is created with the methods quack, swim and fly. Every duck in the system will inherit from the Duck class and therefore inherit those behaviours too.
The problem comes when a new type of duck is introduced into the system which is not supposed to fly: the RubberDuck. If we make this new type to inherit from Duck, we will make the rubber duck fly! That’s wrong.. But if we don’t use inheritance we will have to replicate the quack and swim methods! That’s not really DRY.. So what should we do??
The solution to this is to use composition for the code reuse instead of inheritance. Each of the behaviour that a duck could need -quack, swim, fly – will be separated into a new class –QuackBehaviour, SwimBehavour, FlyBehaviour. Then, each different duck type will use just the needed behaviours.
The code will look like this:
public abstract class Duck { protected IFlyBehavior flyer; public virtual void DoFly() { this.flyer.Fly(); } } public class MallarDuck { public RubberDuck() { flybehaviour = new DoesntFlyBehaviour(); } } public class RubberDuck { public RubberDuck() { flybehaviour = new DoesntFlyBehaviour(); } } public interface IFlyBehavior { public void Fly(); } public class FlyWtihWingsBehaviour: IFlyBehavior { public void Fly() { // Flying coe } } public class DoesntFlyBehaviour: IFlyBehavior { public void Fly() { // Do nothing } }
The example in the book goes deeper and ends up using the Strategy Pattern. I recommend reading that first chapter and the rest of the book if interested. I quite like it, it does not just go about design patterns, but also about main oo principles and why these patterns exist. Also, the first chapter is free in amazon’s look inside or as a sample for the kindle!
In conclusion, inheritance it’s a good way of keeping our code clean and DRY, but it makes sub-classes coupled to their super-classes. Use composition instead of inheritance if possible.
As it says in the book cover, do as Jim and cut down your inheritance! 😉