Using inheritance means that when you call a method (or virtual method in C ++) in the same class, it does not immediately become clear that you can actually call the subclass method. The smell of code that can occur is a call stack that goes up and down the class hierarchy, which in fact means that your superclass and subclass are cyclically dependent.
Using composition and interfaces makes it clear that there are many possible implementations, and also makes it obvious when there is a circular dependency (which usually needs to be removed).
(Composition makes circular dependencies obvious for several reasons (assuming that you use class pass-dependencies through a constructor.) If A and B depend on each other, then either A builds B, or passes this or self to constructor B, which is explicit a sign of circular dependence or some other constructions of the classes of both A and B, which is impossible, since A requires B to be built first, and B requires A to be built first.)
source share