Composition vs Inheritance

is-a vs has-a

This article will help us to understand when to use composition and when to use inheritance. Most of the cases composition is preferred over inheritance.

IS-A Relationship
Has-A relationship
We consider base class which has reusable code.
We consider how things are constructed in small building blocks(interfaces) and attach them to classes
Is this class an X
Does this class have X
code overlap is more
lot of similar verbs/methods, but minimal code overlap
When you use Inheritance, you have to define which class you are extending in code, it cannot be changed at runtime
Composition you just define a Type which you want to use, which can hold its different implementation
Inheritance you can only extend one class, which means you code can only reuse just one class, not more than one
If you want to leverage functionalities from multiple class, you must use Composition. For example, if your code needs authentication functionality, you can use an Authenticater, for authorization you can use an Authorizer etc, but with Inheritance you just stuck with only class
Exposes a subclass to details of its parent’s implementation, so it often breaks encapsulation
Objects are accessed solely through their interfaces, so it won’t break encapsulation

Few reasons why we should prefer composition over inheritance

The big deal is in thinking that one can replace the other, in all cases, or that one is better or worse than the other. Like everything else in software development, there are trade-offs to be made.

  • Inheritance introduces a close relationship between classes. Any change in the parent affects the children’s classes, so you have to be careful and understand how children derive from their superclasses.
  • With composition, it’s easy to change behavior on the fly with Dependency Injection / Setters
  • Inheritance is more rigid as most languages do not allow you to derive from more than one type

Litmus test

  • Does classB want to expose the complete interface (all public methods) of class A such that classB can be used where ever class A is used? This indicates inheritance. Liskov’s substitution principle from SOLID.
    • A BMW will expose the complete interface of a Car class. This makes it fit to inherit from Car class.
    • Follows BMW “is-a” car
  • Does classB only wants some/part of the behavior of classA? This indicates composition.
    • A Bird may need only fly behavior of an Airplane. Here it make sense to extract that common behavior into a separate class and make it a member of both classes.
    • Follow Bird “has-a” flying behavior.