Chapter Seven: Understanding Inheritance
Inheritance is an important concept in object-oriented programming. Using this characteristic, you can define a new class in terms of an existing class in the code. This makes it easy for you to create, maintain, and update any application. Inheritance also allows you to reuse code and its functionality, thereby reducing implementation time when you develop new applications. When you create a class, you do not have to create or write a new class with new function members and data members. As a programmer, you can choose to let a new class inherit members present in an existing class. This class, known as the base class, is used by the derived class.
The objective of inheritance is to create a relationship between the base and derived classes. Consider the following statements:
-
Mammals are animals.
-
Dogs are mammals.
What do you infer from these statements? Dogs are animals. You can develop such relationships in different parts of the code.
Introduction to Base and Derived Classes
You can derive classes from one or more classes in the existing code. This means a class can inherit data, variables, class members, and function members from numerous base classes. You need to use a class derivation list to specify the child or derived class’s base classes. The class derivation list has the following syntax:
class derived-class: access-specifier base-class
In the above syntax, the access specifier is the access specifier modifiers we discussed in the previous chapter – private, public, or protected. The base class is the name of an existing class in the code. If you do not use an access-specifier, then the compiler chooses the private access modifier as the default.
Consider the following example where we are using a Shape class to derive the class Rectangle.
#include <iostream>
using namespace std;
// Base class
class Shape {
public:
void setWidth(int w) {
width = w;
}
void setHeight(int h) {
height = h;
}
protected:
int width;
int height;
};
// Derived class
class Rectangle: public Shape {
public:
int getArea() {
return (width * height);
}
};
int main(void) {
Rectangle Rect;
Rect.setWidth(5);
Rect.setHeight(7)
;
// Print the area of the object.
cout << "Total area: " << Rect.getArea() << endl;
return 0;
}
When you run the above code, you obtain the following output:
Total area: 35
Inheritance and Access
When you use a base class to create a new class, the derived class can access every public and protected member in the base class. If you do not want a derived class to access a specific member in the base class, you should declare those variables should be declared as private members. The following table lists the different forms of access modifiers used in base classes and who can access those members.
Access Modifier
|
Public
|
Protected
|
Private
|
Same class
|
Yes
|
Yes
|
Yes
|
Derived class
|
Yes
|
Yes
|
No
|
Outside classes
|
Yes
|
No
|
No
|
From above, you can see that a derived class can inherit the different members in the base class as long as they are defined as public, except for the following:
-
Friend functions present in the base class
-
Overloaded operators present in the base classes
-
Destructors, constructors, and copy constructors defined in the base class
Inheritance Types
The access modifiers public, private, and protected can be used to determine what members or characteristics the derived class can derive from the base class. Most programmers do not use the access modifiers protected and private when they create derived classes.
They prefer to use the public access modifier since this makes it easier for the derived class to obtain the base class's members and characteristics. You need to apply the following rules when you use inheritance in your code:
Public Inheritance
If you use a public base class to create a derived class, the members in the base class become the members of the derived class. These members will still be public members of the derived class. The derived class also obtains the protected members in the base class, and they remain protected members even in the derived class. If the base class has any private members, the derived class cannot access those members. Having said that, you can use calls to functions to access the private members through protected and public members in the base class.
Protected Inheritance
When you create a derived class from a protected base class, the protected and public members in the base class are accessible to the derived class. They become the protected members of the derived class.
Private Inheritance
When you derive members from a private base class, every member of the base class becomes a private member in the derived class.
Multiple Inheritance
A class in your code can inherit members from one or more classes in the code. You can use the following syntax for the same:
class derived-class: access baseA, access baseB...
The word access in the above syntax is the access modifier (private, public, or protected), and you need to use this keyword against any base class you create in the code. You can separate the base classes in the code using a comma. Look at the following example to understand the same:
#include <iostream>
using namespace std;
// Base class Shape
class Shape {
public:
void setWidth(int w) {
width = w;
}
void setHeight(int h) {
height = h;
}
protected:
int width;
int height;
};
// Base class PaintCost
class PaintCost {
public:
int getCost(int area) {
return area * 70;
}
};
// Derived class
class Rectangle: public Shape, public PaintCost {
public:
int getArea()
{
return (width * height);
}
};
int main(void) {
Rectangle Rect;
int area;
Rect.setWidth(5);
Rect.setHeight(7);
area = Rect.getArea();
// Print the area of the object.
cout << "Total area: " << Rect.getArea() << endl;
// Print the total cost of painting
cout << "Total paint cost: $" << Rect.getCost(area) << endl;
return 0;
}
When you run the above code, you receive the following output:
Total area: 35
Total paint cost: $2450