Object-oriented languages typically support some form of inheritance.
Most languages only support single inheritance. That is, a class can only have one superclass.
Others, notably C++ and the CLOS (Common Lisp Object System), support multiple inheritance.
Still others provide some kind of hybrid. Java only allows single inheritance of implementation, but a class can implement multiple interfaces. Ruby has modules that can be mixed into a class which allows a form of multiple inheritance.
And then there is Visual Basic 6, which only provides interface inheritance. If you want to share implementation, you have to use containment and delegation.
Bertrand Meyer gives a very detailed breakdown of the different ways to use inheritance, along with some advice about which are good and which are bad in his seminal book, Object-Oriented Software Construction. I found an online version of his chapter on inheritance here.
When object-oriented languages first came on the scene, inheritance was one of its most popular features. In many languages, it’s the only way to achieve polymorphism, which is one of the key features of object-orientation. People got excited about modeling the real world with objects and using inheritance to do a taxonomic model of the domain. This eventually caused various kinds of problems.
Over time, we have learned that inheritance is not always the right choice. In fact, implementation inheritance is a very tight form of coupling between two classes, and tight coupling is not generally a good thing. You can use some of the patterns and techniques I’ve been talking about in recent weeks to reduce some of the coupling, but it’s still there.
Some argue that inheritance is evil and should never be used. I disagree. There is still a place for inheritance, but it probably shouldn’t be your first choice.
Just remember, single inheritance is a card that can only be played once, so play it wisely.