"Composition - Functionality of an object is made up of an aggregate of different classes. In practice, this means holding a pointer to another class to which work is deferred.
Inheritance - Functionality of an object is made up of it's own functionality plus functionality from its parent classes."
(from: Steve Rowe's Blog)
More detailed description with examples (Java and UML): Artima development site
"For most non-trivial problems, there will be similar code needed by multiple classes. It is not a wise idea to put the same code in more than one place (a topic for another day). There are two strategies in object-oriented programming which attempt to solve the problem of duplicate code. The one most popular in the early days was inheritance. Shared functionality was implemented in a base class which allowed each child class to inherit that functionality. A child would just not implement foo() and the parent would do the work. This works, but it is not very flexible.
Suppose that the shared functionality is some kind of encryption algorithm. Each child class will only inherit from one base class. What if there are a few different encryption algorithms? It would be possible to have multiple base classes, say AESEncryptionBase and DESEncryptionBase, but this necessitates multiple copies of the child classes--one for each base class. With more than 2 base classes, this become untenable. It also becomes very difficult to change out the encryption routine at runtime. Doing so means creating a new object and copying the contents of the old object to it."
(From: Steve Rowe's Blog)
- fewer code ("It would be possible to have multiple base classes, say AESEncryptionBase and DESEncryptionBase, but this necessitates multiple copies of the child classes--one for each base class.")
- change the routine more easily: if you use a specified Interface (here: to the encryption-classes) you can change the routine whenever you want