I guess a good guideline would be:
When there is an IS-A relationship, use inheritance. Otherwise, use
composition.
The reason for this is related to another concept in Object Oriented Design - polymorphism. Polymorphism is a feature of many OOP languages where an object can be used in place of another object, provided that the class of the first is a subclass of the second.
To illustrate, imagine if you have a function that takes in a type of animal. When you use inheritance, you only have one function:
void feed( Animal a );
Polymorphism assures us that any subclass of animal we put in will be accepted. Otherwise, we will be forced to write one function for each type. I think the benefits of this outweighs its disadvantages (ex. reduced encapsulation).
If there is no IS-A relationship, I think polymorphism won't be very effective. It would thus be better to use composition and have enhanced encapsulation/isolation between classes.