KEMBAR78
Class Inheritance and Hierarchy-2018 | PDF | Inheritance (Object Oriented Programming) | Class (Computer Programming)
0% found this document useful (0 votes)
13 views11 pages

Class Inheritance and Hierarchy-2018

Uploaded by

Emmanuel Mrigo
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views11 pages

Class Inheritance and Hierarchy-2018

Uploaded by

Emmanuel Mrigo
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

CLASS INHERITANCE AND HIERARCHY

References:

1. Pratta S., “C++ Primer Plus”, 6th Edition, 2012, (Adison-Wesley) – Chapter 13, p722.
2. Dietel P. & Dietel H.,”C++ How to Program”, 8th Edition, 2012, (Prentice Hall) –
Chapter 12, p533
3. Malik D.S. “C++ Programming”, 4th Edition, 2011, (Cengane Learning) – Chapter 13,
p764.
4. Bjarne Stroustrup, “C++ Programming Language”, 4th Edition 2013, (Adison-Wesley)
– Chapter 20, p592
5. Android Applications– learn C/C++ chap. 9 & Microlearning C++ chap. 10.

Objectives:

- What inheritance is and how it promotes software reuse.


- The notions of base classes and derived classes and the relationships between them.
- The protected member access specifier.
- The use of constructors and destructors in inheritance hierarchies.
- The order in which constructors and destructors are called in inheritance hierarchies.
- The differences between public, protected and private inheritance.
- To use inheritance to customize existing software.

Introduction:
From Simula programming language, C++ borrowed the ideas of classes and class hierarchies.
In addition, it borrowed the design idea that classes should be used to model concepts (idea, notion,
etc.) in the programmer’s and the application’s world. One of the main goals of object-oriented
programming (OOP) is to provide reusable code. When you develop a new project, particularly
if the project is large, it’s nice to be able to reuse proven code rather than to reinvent it. Employing
old code saves time during program development and since it has already been used and tested,
can help suppress the introduction of bugs into a program. Also the less you have to concern
yourself with details, the better you can concentrate on overall program strategy. For instance,
classes can create new classes from existing classes. This important feature encourages code reuse.
In C++, you can relate two or more classes in more than one way. Two common ways to relate
classes in a meaningful way are:

• Inheritance (‘‘is-a’’ relationship).


• Composition (aggregation) (‘‘has-a’’ relationship).

Inheritance—is a form of software reuse in which you create a new class that absorbs an existing
class’s capabilities (traits, characteristics, features, quality etc.), then customizes or enhances
them to suit a special purpose. In other words, inheritance in C++ takes place between classes;
when the derived class inherits the variables and functions of the base class. These variables and
functions become part of the derived class.

1
Base Classes and Derived Classes:
In other words, one class gets traits from another class. In this case, the trait that is inherited will
be the interface of the superclass class, specifically the (public) methods or functions. A class
that inherits traits from another class is called a subclass. The class being inherited from is the
superclass. A superclass often defines an interface method (or methods) that can be implemented
differently by each subclass. The terms parent class (or base class) are sometimes used instead
of superclass, and the terms child class (or derived class) are sometimes used instead of subclass.

C++ offers public, protected and private inheritance. But, we will concentrate on public
inheritance and briefly explain the other two. With public inheritance, every object of a derived
class is also an object of that derived class’s base class. However, base class objects are not objects
of their derived classes. The notion of a derived class and its associated language mechanisms are
provided to express hierarchical relationships, that is, to express commonality between classes.
For example, the concepts of a circle and a triangle are related in that they are both shapes; that is,
they have the concept of a shape in common. Thus, we explicitly define class Circle and class
Triangle to have class Shape in common. In that case, the common class, here Shape, is referred
to as the base class or superclass and classes derived from that, here Circle and Triangle, are
referred to as derived classes or subclasses. Representing a circle and a triangle in a program
without involving the notion of a shape would be to miss something essential. Moreover, if we
have Vehicle as a base class and Car as a derived class, then all Cars are Vehicles, but not all
Vehicles are Cars—for example, a Vehicle could also be a Truck or a Boat. To emphasize the
inheritance notion, let us see another example, Consider building a program dealing with people
employed by a company. Such a program might have a data structure like this:

class Employee
{
string first_name , family_name;
char middle initial;
int hiring_date;
short department;
long ID_number
...
};

Next, we might try to define a manager:

2
class Manager
{
Employee emp; //manager’s employee record
list<Employee*> group; // people managed
short level;
//
...
};
A manager is also an employee; the Employee data is stored in the emp member of a Manager
object. This may be obvious to a human reader – especially a careful reader – but there is nothing
that tells the compiler and other tools that Manager is also an Employee. A Manager* is not an
Employee*, so one cannot simply use one where the other is required. In particular, one cannot
put a Manager onto a list of Employees without writing special code. We could either use explicit
type conversion on a Manager* or put the address of the emp member onto a list of employees.
However, both solutions are inelegant and can be quite obscure. The correct approach is to
explicitly state that a Manager is an Employee.

The Manager is derived from Employee, and conversely, Employee is a base class for Manager.
The class Manager has the members of class Employee (first_name, department, etc.) in
addition to its own members (group, level, etc.). Derivation is often represented graphically by a
pointer from the derived class to its base class indicating that the derived class refers to its base
(rather than the other way around):

A derived class is often said to inherit properties from its base, so the relationship is also called
inheritance. A base class is sometimes called a superclass and a derived class a subclass. This
terminology, however, is confusing to people who observe that the data in a derived class object
is a superset of the data of an object of its base class. A derived class is typically larger (and never
smaller) than its base class in the sense that it holds more data and provides more functions.

Let's move on to the syntax: To specify that class TwoDimensionalShape (see figure above) is
derived from (or inherits from) class Shape, class TwoDimensionalShape’s definition could
begin as follows:

3
class TwoDimensionalShape : public Shape // syntax for single inheritance

This is an example of public inheritance, the most commonly used form (private inheritance and
protected inheritance will be dealt with in other sections). With all forms of inheritance, private
members of a base class are not accessible directly from that class’s derived classes, but these
private base-class members are still inherited (i.e., they’re still considered parts of the derived
classes).With public inheritance, all other base-class members retain their original member access
when they become members of the derived class (e.g., public members of the base class become
public members of the derived class, and, as we’ll soon see, protected members of the base class
become protected members of the derived class).Through these inherited base-class members, the
derived class can manipulate private members of the base class(if these inherited members provide
such functionality in the base class). In principle, a derived class inherits every member of a base
class except the following:
 Its constructors and its destructor
 Its assignment operator members (operator=)
 Its friends function(s).

Although the constructors and destructors of the base class are not inherited as constructors and
destructors in the derived class, they are still called by the derived class's constructor. Unless
otherwise specified, the constructors of derived classes call the default constructors of their base
classes (i.e., the constructor taking no arguments), which must exist.

Consider the following example:

class Drawable // superclass definition


{
public:
void draw (); // class method
};

This simple class, Drawable, defines only a single method—draw ( ). This method draws the
current object.

class Ship : public Drawable //ship’s inheritance from Drawable


{
};

The “: public Drawable” indicates that the class Ship inherits from the class Drawable. By
writing this code, Ship inherits all public methods and public data from its superclass,
Drawable. Right now, Ship has inherited the method draw (). The full method, in fact. If you
were to write:
Ship s;
s.draw();
The call to draw () would invoke the implementation of the draw () method that was written into
Drawable.

4
The above notion is supported by the following simple program:
1 // Base classes and derived classes
2 #include <iostream>
3 using namespace std;
4
5 class Polygon { //2D Base class definition
6 protected:
7 int width, height;
8 public:
9 void set_values (int a, int b) //set function
10 {width=a; height=b;}
11 };//End of Base class definition.
12
13 class Rectangle: public Polygon { //single inheritance from Polygon class to Rectangle class
14 public:
15 int area ()
16 { return width * height; }//enhancement or customization or adaptation
17 };
18
19 Triangle: public Polygon { //single inheritance from Polygon class to Triangle class
20 public:
21 int area ()
22 {return width * height / 2; }// enhancement or customization or adaptation
23 };
24
25 int main () { // Main function starts here
26 Rectangle rect; //class instance
27 Triangle trgl; // class instance
28 rect.set_values (4,5);
29 trgl.set_values (4,5);
30 cout<<"Area of a Rectangle is : ";
31 cout << rect.area() << " sq. units \n";
32 cout<<"Area of a Triangle is : ";
33 cout << trgl.area() << " sq. units \n";
34 return 0;
35 }

Protected Members:
A base class’s public members are accessible within its body and anywhere that the program has
a handle (i.e., a name, reference or pointer) to an object of that class or one of its derived classes.
A base class’s private members are accessible only within its body and to the friends of that base
class. Protected access offers an intermediate level of protection between public and private
access. A base class’s protected members can be accessed within the body of that base class, by
members and friends of that base class, and by members and friends of any classes derived from
that base class.

5
Derived-class member functions can refer to public and protected members of the base class
simply by using the member names. When a derived-class member function redefines a base-class
member function, the base-class member can still be accessed from the derived class by preceding
the base-class member name with the base-class name and the scope resolution operator (::).
class A
{
public:
int x;
protected:
int y;
private:
int z;
};

class B : public A//Public single inheritance


{
// x is public
// y is protected
// z is not accessible from B
};

class C : protected A//Protected single inheritance


{
// x is protected
// y is protected
// z is not accessible from C
};

class D : private A // 'private' is default for classes


{
// x is private
// y is private
// z is not accessible from D
};

Redefining (Overriding) Member Functions of the Base Class:


Suppose that a class derivedClass is derived from the class baseClass. Further assume that both
derivedClass and baseClass have some member variables. It then follows that the member
variables of the class derivedClass are its own member variables, together with the member
variables of baseClass. Suppose that baseClass contains a function, print, that prints the values
of the member variables of baseClass. Now derivedClass contains member variables in addition
to the member variables inherited from baseClass. Suppose that you want to include a function
that prints the values of the member variables of derivedClass. You can give any name to this
function. However, in the class derivedClass, you can also name this function as print (the same

6
name used by baseClass). This is called redefining (or overriding) the member function of the
base class. An example to illustrate this, see next under “Overriding Base Class Functions”.

Constructors of Derived and Base Classes:


A derived class can have its own private member variables, so a derived class can explicitly
include its own constructors. A constructor typically serves to initialize the member variables.
When we declare a derived class object, this object inherits the members of the base class, but
the derived class object cannot directly access the private (data) members of the base class.
The same is true for the member functions of a derived class. That is, the member functions of
a derived class cannot directly access the private members of the base class.

As a consequence, the constructors of a derived class can (directly) initialize only the (public
data) members inherited from the base class of the derived class. Thus, when a derived class
object is declared, it must also automatically execute one of the constructors of the base class.
Because constructors cannot be called like other functions, the execution of a derived class’s
constructor must trigger the execution of one of the base class’s constructors. Furthermore, a
call to the base class’s constructor is specified in the heading of the definition of a derived class
constructor.

//class Inheritance
//specifying a costructor to be called in derived class
#include <iostream>
using namespace std;

class Rectangle //base class


{
private :
float length;
float width;
public:
Rectangle () //base class default constructor
{
length = 0;
width = 0;
}

Rectangle (float len, float wid) //base class parameterized constructor


{
length = len;
width = wid;
}

float area() // base class method (or function)


{
return length * width ;

7
}
};

class Box : public Rectangle //single public inheritance


{
private : //derived class private members
float height;
public:
Box () //default constructor for derived class
{
height = 0;
}

//parameterized constructor from base class is called


Box (float len, float wid, float ht) : Rectangle(len, wid)
{
height = ht;
}

float volume() // derived class meber function (method)


{
return area() * height;
}
};

int main ()
{
Box bx; // derived class instances creeated
Box cx(4,8,5);
cout << bx.volume() << endl; //dot operator used to call class method
cout << cx.volume() << endl;
return 0; //return control to OS.
}

We can summarize the different access types according to which functions can access them in
the following way:

Access public protected private


members of the same class yes yes yes
members of derived class yes yes no
not members yes no no

Where "not members" represents any access from outside the class, such as from main, from
another class or from a function (friend class and friend function).

8
In the example above, the members inherited by Rectangle and Triangle have the same access
permissions as they had in their base class Polygon:
1 Polygon::width // protected access
2 Rectangle::width // protected access
3
4 Polygon::set_values() // public access
5 Rectangle::set_values() // public access

This is because the inheritance relation has been declared using the public keyword on each of the
derived classes:
class Rectangle: public Polygon { /* ... */ }

This public keyword after the colon (:) denotes the most accessible level the members inherited
from the class that follows it will have from the derived class. Since public is the most accessible
level, by specifying this keyword the derived class will inherit all the members with the same
levels they had in the base class. With protected, all public members of the base class are
inherited as protected in the derived class. Conversely, if the most restricting access level is
specified (private), all the base class members are inherited as private and thus cannot be
accessed from the derived class. e.g., if daughter were a class derived from mother that we defined
as:
class Daughter: protected Mother;

This would set protected as the less restrictive access level for the members of Daughter that it
inherited from mother. That is, all members that were public in Mother would
become protected in Daughter. Of course, this would not restrict Daughter from declaring its own
public members. That less restrictive access level is only set for the members inherited
from Mother.

If no access level is specified for the inheritance, the compiler assumes private for classes
declared with keyword class and public for those declared with struct.

Overriding Base Class Functions


A derived class can override a member function of its base class by defining a derived class
member function with the same name and parameter list. It is often useful for a derived class to
define its own version of a member function inherited from its base class. This may be done to
specialize the member function to the needs of the derived class. When this happens, the base class
member function is said to be overridden by the derived class.

//class inheritance
//overriding a base class method
#include <iostream>
using namespace std;

9
class mother
{
public:
void display () //base class method
{
cout << "mother: display function\n";
}
}; // end of base class defn

class daughter : public mother //public single inheritance


{
public:
void display () //derived class method
{
cout << "\n daughter: display function\n\n";
}
};// end of derived class defn

int main ()
{
daughter rita; //class object created
rita.display(); //function called
return 0;
}
output:
daughter: display function

Gaining Access to an Overridden Function

It is occasionally useful to be able to call the overridden version. This is done by using the scope
resolution operator to specify the class of the overridden member function being accessed.

class daughter : public mother


{
public:
void display ()
{
cout << "daughter: display function\n\n";
mother::display();
}
};

output:
daughter: display function
mother: display function

10
Virtual Base Class

Multipath inheritance may lead to duplication of inherited members from a grandparent base class.
This may be avoided by making the common base class a virtual base class. When a class is made
a virtual base class, C++ takes necessary care to see that only one copy of that class is inherited.

class A
{
.....
.....
};

class B1 : virtual public A


{
.....
.....
};

class B2 : virtual public A


{
.....
.....
};

class C : public B1, public B2


{
.....// only one copy of A
.....// will be inherited
};

11

You might also like