Choosing composition or inheritance is, in most cases, a matter of what seems to be the most natural.
When I explain object-oriented concepts to beginners, I use the example of writing a set of classes to represent cars. Composition relationships exist between a car class, e.g. Car, and the classes for its parts, e.g. Engine, Tire, SteeringWheel, etc. A Car object has an Engine object, a set of Tire objects, a SteeringWheel object, etc. The "has-a" description is typically how a composition relationship is identified.
Inheritance relationships, on the other hand, exist between classes which naturally share most of their characteristics. In the cars example, different kinds of cars could be represented by subclasses of the Car class. For instance, a CompactCar class inheriting from the Car class makes sense because a compact car is a car. The "is-a" description is typically how an inheritance relationship is identified.
From a programming standpoint, most object-oriented programming language allow inheriting from only one class (i.e. single inheritance). Single inheritance rules out using inheritance for "has-a" relationships like those in the cars example above. That is, in most languages, the Car class could not inherit from both the Engine class and the SteeringWheel class, for example, even if it made sense to do so. Therefore, a class with composition relationships to other classes has to implement its own methods to make any methods of the other classes available. For instance, the Engine class might have a start() method, but, because the Car class has an Engine object, the Car class must have its own method, e.g. start(), which calls the Engine object's start() method. The benefit of using inheritance is avoid having to write methods that call other classes' methods. A subclass automatically inherits the methods from its superclass, so it does not need to have its own methods to call the superclass methods unless it needs to change what a method does.
A lot of programming is a matter of convention and object-oriented programming is no different. The "has-a" and "is-a" identification of composition versus inheritance is a matter of convention. Ultimately, how you choose to write your program is a matter of how it makes sense to you and how it allows you to reuse your code efficiently.