Inheritance is the single hairiest OOP feature. In Object-Oriented Analysis and Design, Grady Booch describes inheritance as follows:
A relationship among classes, wherein one class shares the structure or behavior defined in one (single inheritance) or more (multiple inheritance) other classes. Inheritance defines an "is-a" heirarchy among classes in which a subclass inherits from one or more generalized superclasses; a subclass typically specializes its superclasses by augmenting or redefining existing structure or behavior.Ugh. Here is what it boils down to: when you have two types A and B, where an instance of B can logically be used anywhere an instance of A is used, you can probably define an inheritance relationship between them.
Here, both a circle and a triangle are shapes. Anything we can do with a Shape, we expect to be able to do with a Circle or a Triangle, because these are kinds of Shapes. However, the reverse is not true. Circle and Triangle are not merely instances of shape, for several reasons:
We expect to be able to perform operations on a certain subtype of Shape (e.g., getting a Circle's radius) that do not make sense for an arbitrary shape.
It would be ugly and inefficient to devise a single Shape class that could represent any arbitrary shape.
Therefore, we use inheritance. We say that these classes are subclasses of Shape; they specialize Shape for a particular use. In turn, Shape is the superclass of Circle and Triangle.
In the C++ world, it is common to use the term base class for superclass and derived class for subclass.