You are on page 1of 12

UNIVERSITY OF ESWATINI

FACULTY OF SCIENCE & ENGINEERING


DEPARTMENT OF ELECTRICAL AND ELECTRONIC
ENGINEERING

LECTURE NOTES
ON PROGRAMMING TECHNIQUES 2

LECTURE 13
Inheritance

2
Introduction
Complex classes can be constructed from simpler classes by;

1. Composition – new objects are built from small objects


a. It models a “has-a” relationship, see example 1
2. Friendship of classes
3. Inheritance – it models a “is-a” relationship,
a. A new class is derived from an old class without changing the class
b. The parent class(base class) is not modified by the new class(derived class)
can use all the features of the parent class, and adds its own features
c. Example of an ”is-a” object relationship; A manager is an employee, a CEO
is an employee

Definition: Inheritance is a way of relating two or more classes so that one class may use
another class’s members without redefining them

Example 1 (class composition)

class Something;
class Simple
{
private:
int X;
Something S;

public:
Simple(int x1, Something S1)
{
X = x1;
S = s1;
}
};

class Something
{
private:
int a;

public:
Something(int a1 = 0) :a(a1)
{

}
};

int main()
{
Something So(3);//simpler object
Simple simpleton(4, So);//complex object built from simpler object
}

Inheritance terminology and syntax


- The parent class (inherite from) is called a base class/superclass

3
- The child class is called a derived class/ sub class
- Children often redefine the attributes and behaviours they inherit
- They may also add their own attributes and behaviours
- Inheritance requires that there is a base class and a derived class
- The base class does not need any special syntax
- On the other hand in the derived class it must be declared that it has been derived from
the base class
- This is done by placing a colon after the name of the derived class followed by a keyword
such as “public” and then the base class name

class <Derived class_name> :<type_of_inheritance> <Base class_Name>


{
//rest of the class here
};

class Derived :public Base


{
//rest of the class here
};

Example: Teacher and principal in a school

class Teacher Teacher // Base class


{
private:
string name;
int age, numberOfStudents;
public:
void setName(const string & new_name)
{
name = new_name;
}

void print() const;


};

class Principal Principal : public Teacher // Derived class


{
private:
string schoolName; // Additional members
int numberOfTeachers;

public:
void setSchool(const string & s_name)
{
schoolName = s_name;
}

void print() const;


};

int main()
{
Teacher t1;

4
Principal p1;
p1.setName(" Principal 1");// Since principal is a teacher P1 can
use setName
t1.setName(" Teacher 1");
p1.setSchool(" Elementary School");// p1 can also use setSchool
return 0;
}

Class member redefinition


- Some inherited members may not be suitable for the derived class
- These members may have to be redefined in the derived class (overidden)

Example
void Teacher::print() const
{
cout << "Name: " << name << " Age: " << age << endl;
cout<<Number of students: "<<numOfStudents<<endl;
}

void Principal::print() const


{
cout << "name:" << name << " Age: " << age << endl;
cout << "Number of Students:" << numOfStudents << endl;
cout << "Name of the School:" << school_name << endl;
}

- The print() function of the principal class overrides the print() function of the teacher
class
- Principal class therefore has two print functions
- The print function in the base class can be accessed by a scope resolution operator (::) as
shown below
void Principal::print() const
{
Teacher::print();
cout << "Name of the School:" << school_name << endl;
}

Access Control
- We know that public class members functions have direct access to private members of
the class
- Objects of the class have direct access only to public members
- However members of a derived class can only directly access public members of the base
class
- Objects of a derived class can only access public members of the base class

The protected access specifier


- We have seen that a member of a class can be public, or private
- In C++ there is one more access specifier protected

5
- A member under a protected access specifier can be accessed by member and friend
functions of the class and that of any derived class
- Except for derived classes , a data member that is marked protected is treated the same as
if it were private from outside the class

Table: Access control effect on derived class member function

Access Specifier Base Class Derived Class Object


private Yes No No
protected Yes Yes No
public Yes Yes Yes

Example

class Teacher //Base class


{
private: // can only be accessed by members of class Teacher
string name;

protected: // Can be accessed by members of Teacher and Principal


int age, numOfStudents;

public: // Can be directly accessed outside the class


void setName(const string & new_name)
{
name = new_name;
}
void print() const;
};

class Principal : public Teacher //Derived class


{
private:
string school_name;
int numOfTeachers;
public:
void setSchool(const string & s_name)
{
school_name = s_name;
}
void print() const;
int getAge() const
{
return age;
} // it will work because data member age is under protected
const string & get_name()
{
return name;
}// ERROR! name is private
};

int main()
{
teacher t1;
principal p1;
t1.numberOfStudents = 54;

6
t1.setName("Amos Maseko");
p1.setSchool("Kwaluseni High School");
}

Note:

- In general all data members should be made private to ensure the integrity of the data, but
access to this data via set/get functions can be a time-consuming process. As such data
may be defined as protected to make derived classes access data directly and faster.

Public Inheritance
- The most common form of inheritance is public inheritance which is made by using the
access specifier public.
class Base
{

};

class Derived : public Base


{

};

- In public inheritance the access rights of the members of the base class are not changed.
- Objects of the derived class can access public members of the base class.
- Public members of the base class are also public members of the derived class.

Private Inheritance
- Another form of inheritance is private inheritance which is made by using the access
specifier private as shown below
class Base
{

};

class Derived : private Base


{

};

- In private inheritance public members of the base class are private members of the
derived class.
- Objects of the derived class cannot directly access public members of the base class.
- Member functions of the derived class can still access public and protected members of
the base class.

7
Redefinition of access in inherited members
- The access specifications of privately inherited public members of the base class can be
redefined in the derived class from private to public.
o When a derived class inherits privately public members of the base class
become private to objects of the derived class.
- If you need specific public members of the base class to be public, just declare them again
as public by mentioning their name and the class where they belong (use the scope
resolution operator) under the public access specifier of the derived class.
- There is no need to include the return type and arguments,

Example
class Teacher //Base class
{
private:
string name;

protected:
int age, numOfStudents;

public:
void setName(const string & new_name)
{
name = new_name;
}

string& getName() const


{
return name;
}

void print() const;


};

class Principal : private Teacher //class Teacher members inherited privately


{
private:
string school_name;
int numOfTeachers;
public:
Teacher::setName();// setName() has become public again
void setSchool(const string & s_name)
{
school_name = s_name;
}
void print() const;
int getAge() const
{
return age;
} //
const string& get_name()
{
return getName();
}
};

8
Constructors and Inheritance
- When an object of the derived class is defined, the base class constructor is called before
calling the derived class constructor
- It is done this way because the base class members form a part of the whole object
created by the derived class
- Put differently, you need to construct the parts before you can construct the whole
- If the base class has a constructor that needs arguments, this constructor must be called
before the constructor of the derived class is called.

Example

class Teacher //Base class


{
private:
string name;

protected:
int age, numOfStudents;

public:
Teacher(string nam, int age1, int num_S) : name(nam), age(age1),
numOfStudents(num_S)
{

}
void setName(const string & new_name)
{
name = new_name;
}

string& getName() const


{
return name;
}

void print() const;


};

class Principal : public Teacher


{
private:
string school_name;
int numOfTeachers;

public:
Principal(string nam, int age1,int num, string s_nam, int
num_T);//declaration of derived class constructor
void setSchool(const string & s_name)
{
school_name = s_name;
}
void print() const;
int getAge() const
{

9
return age;
} //
const string& get_name()
{
return getName();
}
};
// Definition of derived class constructor
// constructor of the base is called before the body of the constructor of the derived
class
Principal::Principal(string nam, int age1, int num, string s_nam, int num_T)
:Teacher(nam, age1, num), school_name(s_nam), numOfTeachers(num_T)
{
//left empty
}

int main()
{
teacher t1("Ayanda Dlamini", 20, 25);//object of base class
principal p1("Amos Maseko", 35, 21, "Kwaluseni_High", 87);//Object of Derived
class
return 0;
}

Note:

- If the base class has a constructor, which must take some arguments, then the derived
class must also have a constructor that calls the constructor of the base with proper
arguments.

Inheritance Hierarchy
- Inheritance relationships form class hierarchies where derived classes extend from a base
class according to how they depend on each other
- The figure below illustrate a 3 level class hierarchy where class C inherits from class B
and class B inherits from class A, meaning class A is the base class
- Since at each inheritance level the classes B and C inherit from one class, this is called
single inheritance
- Otherwise if a class inherits from more than one class this is called multiple inheritance

10
Class A

int Xa, float Ya

printA

Class B

int Xb, float Yb

printB

Class C

int Xc, float Yc

printC

Figure 3: Inheritance hierarchy for class A,B, and C

Example:
Program based on inheritance hierarchy shown in Figure 3. Constructors for each class are
included, and print function is redefined.
#include <iostream>
using namespace std;

class A
{
private:
int Xa;
float Ya;

public:
A(int Xa1, float Ya1) : Xa(Xa1), Ya(Ya1)// initialize A
{

void print()
{
cout << "The values of class A are: " << Xa << "," << Ya << "/n";
}
};

class B: public A
{
private:
int Xb;
float Yb;

public:
//Initialize A and B
B(int Xa1, float Ya1, int Xb1, float Yb1) : A(Xa1, Ya1), Xb(Xb1), Yb(Yb1)
{

11
}

void print() //print has been redefined


{
A::print();
cout << "The values of class A are: " << Xb << "," << Yb << "/n";
}
};

class C : public B
{
private:

int Xc;
float Yc;

public:
//Initialize B and C
C(int Xa1, float Ya1, int Xb1, float Yb1, int Xc1, float Yc1) : B(Xa1, Ya1,
Xb1, Yb1), Xc(Xc1), Yc(Yc1)
{

void print() //print has been redefined


{
B::print();
cout << "The values of class A are: " << Xc << "," << Yc << "/n";
}
};

int main()
{
C Object(3, 3.1, 5, 3.2, 7, 2.1);
Object.print();
return 0;
}

Note:

- The constructor in each class must take enough arguments to initialize the data for the
class and all “ancestor” classes.
- This means two arguments for the A class constructor, four for B (which must initialize A
as well as itself), and six for C (which must initialize A and B as well as itself).
- Each constructor calls the constructor of its base class.

Exercise
These fruits, apples, bananas, oranges, lemons, and tangerines are related as shown in the
inheritance hierarchy figure below. Drawing insights from the last example write a program
that demonstrates the inheritance hierarchy. You are free to add member functions of your
choice.

12
Fruit

String Color, int Quantity,

printF()

Apple Banana Citrus_Fruit

String Color, int Quantity, Char Season String Color, int Quantity, float weight String Color, int Quantity,float PH

printF() printF() printF()

Orange Lemon

String Color, int Quantity,float PH String Color, int Quantity,float PH

printF() printF()

Figure 4: Inheritance hierarchy for Fruits

Note:

- Deadline: Mid_night (24:00Hrs) ,05th of August 2020


- Submission must be done in moodle

13

You might also like