Inheritance and composition

If inheritance were a better long term solution than composition, babies would never come out of the womb.

I like to learn from nature. It has a lot of experience. Many orders of magnitude more experience than I would be able to accumulate in a lifetime.

An interesting analogy between Object Oriented Programming and nature can be found when reasoning about Inheritance and Composition.

Here is a simple example of inheritance in Ruby:

In this example the child relies on the mother’s eating mechanism in order to get nutrition and grow. The child doesn’t know how the mother extracts nutrition from food, he is just given nutrition which he then uses to grow.

One of the problems with this design is that if the mother changes its eating logic, e.g. by not storing nutrition in the @nutrition attribute, the child doesn’t get any nutrition to use. The child also has to ensure that the mother’s eating logic is called before its own. It does this by calling super before calling grow. The child cannot invert the order of the calls if he wants to get access to the nutrition.

Let’s look at a different example:

In this case the mother feeds the child, who independently extracts and uses nutrition from the food.

It doesn’t necessarily need to be the mother that feeds the child. As long as somebody feeds the child, the child will grow. In fact, we can imagine the mother and the child being part of a family, which has the responsibility of feeding its members:

The first example is similar to a baby in a womb, who cannot process food directly yet and relies on the mother’s digestive mechanisms to get access to nutrition. An instance of the child is also an instance of the mother.

In the second example the child is capable of processing food independently, is out of the womb and therefore only dependent on somebody feeding him. We use dependency injection in order to allow the mother to feed the child. An instance of the child is not an instance of the mother. Mother and child must be instantiated separately, and the child has to be given to the mother in order for the child do be fed.

The trade-off of duplicating the nutrition extraction logic has made the child independent and has solved the problems that were consequences of inheritance coupling.

In the third example we decouple the mother and the child and move the responsibility of feeding both mother and child to a family class.

Under this perspective, nature seems to prefer composition over inheritance as a long term solution.

A final note

The analogy is based on a perspective that could be inverted. It is possible to assert with equal confidence that a child inherits behaviours from a mother which he preserves after birth and that a child in the womb of its mother represents a composition. In the end it’s about the design that best endures the test of time and change for the specific problem. Nevertheless, I find it fascinating to relate logical thinking to the evolutionary patterns of nature.