Before defining inheritance a review of what is meant by being accessible and the access specifiers is in order.
What did accessibility mean with respect to structures?
In C++ we could define a structure as follows:
struct Date { int month, day, year; }; Date invoiceDate;
However, this did not lead to accessibility like the following:
month = 11; day = 1; year = 2006;
because the variables: month, day and year do not exist independently by themselves. They are part of an object of the class Date.
Instead what is meant is by accessible is with respect to an instance of the structure as in:
invoiceDate.month = 11; invoiceDate.day = 1; invoiceDate.year = 2006;
How has accessibility changed for C++ classes?
In C++ an additional restriction to accessibility has been added: member as well as object accessibility. In addition the object accessibility depends on the access specifiers: private, protected and public. Member accessibility is as follows:
Specifier Where Declared | By Members or Objects inside of the class? | By Objects outside of the class? |
---|---|---|
private | Accessible | Not Accessible |
protected | Accessible | Not Accessible |
public | Accessible | Accessible |
Inheritance adds another level of accessibility between the parent class and the child class in an extension. This is done by overloading the meaning of the keywords: private, protected, and public. The construct of class inheritance is:
class DerivedClass : accessSpecifier1 BaseClass1, accessSpecifier2 BaseClass2, .... accessSpecifierN BaseClassN { .... };
The classes: BaseClass1, BaseClass2, .... BaseClassN are called the parents and the DerivedClass is called the child class. With inheritance, the parents are also called the base classes and the child class is also called the derived class. If N = 1, the extension is called a single/serial inheritance and otherwise the extension is referred to as a multiple inheritance.
Note: Using multiple inheritance can cause problems. As a result some say that you should not use multiple inheritances. As a result, it is recommended that you use multiple inheritances very rarely. This concept is considered so dangerous that it is has been eliminated in the new language C#. The problem of multiple inheritances will be discussed further in the lecture on virtual classes.
In the definition of a derived class each accessSpecifierX above may be: private, protected, public or left blank. If the access specifier is left blank, then private is the default when the "class" is a class and public when the "class" is a structure.
A private extension is not very useful. A protected extension is better but not by much. A public extension is generally the best choice. Which one of these should be used and where should it be used will only come with experience. What must be kept in mind is whether there are going to be any additional extensions of the derived class. When this happens, any new derived class can not have more access to the original base than its parent (in other words the one in the middle or the original derived class.)
If the base class is defined as follows:
class BaseClass { private: .... protected: .... public: .... };
then any one of the following extensions is possible. For example a private extension:
class Derived1 : private BaseClass { .... };
or a protected extension:
class Derived2 : protected BaseClass { .... };
or a public extension:
class Derived3 : public BaseClass { .... };
Members in the private access section of the base class are never accessible by members nor objects of the derived class. The other members of the base class have the accessibility as represented in the following table:
Extension Type | Base Member's Section | Appears as derived section |
---|---|---|
private | private | not accessible |
protected | private | |
public | private | |
protected | private | not accessible |
protected | protected | |
public | protected | |
public | private | not accessible |
protected | protected | |
public | public |
Some examples of serial inheritances are: PrivateInheritance.cpp, PublicInheritance.cpp, ProtectedInheritance.cpp.