Inheritance is a concept that is easily understood because the word itself has a lot of context to it. Inheritance can be best understood by this phrase “If your parents are Filipino, you would also be Filipino”. Characteristics and traits of parents are inherited downward to children who may or may not use them.
Composition on the other hand is a different approach to passing around functionality. A good way to visualize it is to look at how cars are built. We do not get daddy and mommy cars to make baby cars. We take different parts of the car and put them together to compose a car. This is how composition works.
Both techniques are widely used in object oriented design to create objects. Inheritance is more popular because of its obvious code reusability. Abilities of the parent class are inherited by the child classes (no extra coding required!). But this very strong reuse of code comes with a heavy price, tight coupling. As software developers, we try to de-couple as much as possible to make separation of these functionalities in the future a lot easier (the same way some people like to have relationships with no strings attached!).
How do we then achieve the same amount of reusability without the hassles of having strings attached you ask? The answer is interfaces, delegation and composition. Composition is a way of creating objects by using functionalities of other objects. Delegation is a way to trigger these functionalities without knowing which object is going to do the actual work. Interfaces are contracts between these collaborating objects so that they can be easily interchangeable with other objects.
Creating these different levels of indirection may look costly at first (and it is) but the benefits are long term. Of course there is such a thing as too much indirection. This is where you get a universal tool that needs 2 days to prepare just to hit a single nail on the head once a year (at least now its ready for anything, right?).