0% found this document useful (0 votes)
7 views

Inheritance

NOTES
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

Inheritance

NOTES
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 42

INHERITANCE

 Why?

 What?

 How?
INHERITANCE
 Inheritance is the process by which a new class known
as a derived class is created from another class, called
the base class.
 A derived class automatically has all the member
variables and functions that the base class has and can
have additional member functions and/or additional
member variables.
 The definition of a derived class begins like any other
class definition
but is followed by:
 a colon
 the reserved word public
Indicating inheritance
Example:
class HourlyEmployee : public Employee

 Using the keyword public, the derived class


(HourlyEmployee) automatically receives all the public
member variables and member functions of the base
class (Employee).
 In addition to the inherited member variables and
member functions, a derived class can add new
member variables and new member functions.
 The new member variables and the declarations for
the new member functions are listed in the class
definition.
Indicating inheritance
Example:
class HourlyEmployee : public Employee

NOTE:
 The definition of the derived class
(HourlyEmployee) only lists the added
member variables. The member variables
defined in the base class (Employee) are
not re-defined. They are automatically
available to the derived class.
 You do not give the declarations of the
inherited member functions except for
those whose definitions you want to
change (redefine).
Constructors in Derived Classes

 A constructor in a base class is not inherited in the


derived class, but you can invoke a constructor of the
base class within the definition of a derived class
constructor.
 The base class constructor initializes all the data
inherited from the base class.
 Thus, a constructor for a derived class begins with an
invocation of a constructor for the base class (within
the initialization section of the constructor definition).
Constructors in Derived Classes

 The call to the base class constructor is the first action


taken by a derived class constructor.
 If class B is derived from class A and class C is derived
from class B, then when an object of the class C is
created, first a constructor for the class A is called, then
a constructor for B is called, and finally the remaining
actions
A of the C constructor are taken.

C
Constructors in Derived Classes

 If you do not include a call to a constructor of the base


class, then the default (zero-argument) constructor of the
base class will automatically be called when the derived
class constructor is called.
 N.B. If you do not provide a default constructor, then C++
will automatically generate a constructor for you. However,
this default copy constructor simply copies the contents of
member variables and does not work correctly for classes
with pointers or dynamic data in their member variables.
 Preferably always explicitly include a call to a base class
constructor prior to assigning the child class variables.
OBJECT SCOPE
 An object of a class type can be used anywhere that an
object of any of its ancestor classes can be used.
 If class Child is derived from class Ancestor and class
Grandchild is derived from class Child, then an object
of class Grandchild can be used anywhere an object of
class Child can be used, and the object of class
Grandchild can also be used anywhere that an object
of class Ancestor can be used.
REDEFINING
 The definition of an inherited member function can be changed in the
definition of a derived class so that it has a meaning in the derived class
that is different from what it is in the base class. This is called redefining the
inherited member function.
 When a member function is redefined, you must list its declaration in the
definition of the derived class even though the declaration is the same as in
the base class.
 The signatures of the member functions in the base class and derived class
will be the same.
e.g. In base class: double calcPay()
In child class: double calcPay()
REDEFINING VS OVERRIDING
 Both refer to changing the definition of the function in
a derived class.
 If the function is a virtual function, it is called
overriding.
 If the function is not a virtual function, it is called
redefining.
VIRTUAL FUNCTIONS
 It is legal to assign a derived class object to a base class
object i.e. parentObj = childObj.
 However, a parent class object will not have all of the
variables of the child class.
 Assigning a derived class object to a base class object slices
off data i.e.
 Data members from the derived class not in the parent
class will be lost.
 Member functions not defined in the base class are
similarly unavailable to the resulting base class object.
VIRTUAL FUNCTIONS
 It is permissible to assign a derived class object to point to a base
class object i.e. pointerAncestor = pointerDescendant
if pointerAncestor is a base class for the type of
pointerDescendant.
 None of the data members or member functions of the dynamic
variable being pointed to by pointerDescendant will be lost.
 However, you need virtual functions to access them.
 Virtual function – in a nutshell:
I am defining a function here but wait until the function is being
used in a program and branch to the implementation that
corresponds to the actual object calling this function.
USING VIRTUAL FUNCTIONS
 If a function has a different definition in a derived class than in
the base class and you want it to be a virtual function, you add
the keyword virtual to the function declaration in the base
class.
 You do not need to add virtual to the function declaration in the
derived class. If a function is virtual in the base class, then it is
automatically virtual in the derived class.
(Good OOP principle to label the function declaration in the
derived class virtual, even though it is not required.)
 The reserved word virtual is added to the function declaration
- not to the function definition.
USING VIRTUAL FUNCTIONS
But….
 The compiler and the run-time environment need to do
much
more work for virtual functions.
 The more virtual functions the less efficient your
programs will be.
DESTRUCTORS
 If the base class destructor is not virtual:
 When a delete operation is performed on a dynamic
variable pointing to the Derived class, only the
destructor for the Base class will be invoked.
 The memory for the dynamic variable pointed to will
be returned to the freestore, but the memory for the
dynamic variable pointed to by the child class object
will never be returned to the freestore (until the
program ends).
DESTRUCTORS
 If the base class destructor is virtual:
 When a delete operation is performed on a dynamic variable
pointing to the Derived class the destructor for the class Derived
will be invoked (since the object pointed to is of type Derived).
 The destructor for the Derived class will delete the dynamic
variable pointed to and then automatically invoke the destructor
for the Base class.
 The Base class destructor will delete the dynamic variable
pointed to.
 All the memory is returned to the freestore when the base class
destructor is marked as virtual.
DESTRUCTORS
Therefore …
Best to always define all destructors as virtual.

A Destructor A

B Destructor B Order of calls to destructors

C Destructor C
PRIVATE MEMBER VARIABLES

 Member variables (or member functions) that are private in a base


class are not accessible by name in the definition of a member
function for any other class, not even in a member function definition
of a derived class.
Private member variables are inherited, but it is illegal to directly
access them by name outside of the class in which they have been
defined. Solution: code accessor and mutator methods.
Private member functions are not accessible outside of the interface
and implementation of the base class. Private member functions
should be limited to the class in which they are defined.
PROTECTED MEMBER VARIABLES

 Member variables (or member functions) that are protected in a base


class are not accessible by name in the definition of a member
function for any class other than the derived class.
Protected member variables and functions are directly accessible by
the class in which they have been defined and any class that inherits
from this class.
PROTECTED MEMBER VARIABLES

 Member variables (or member functions) that are protected in a base


class are not accessible by name in the definition of a member
function for any class other than the derived class.
Protected member variables and functions are directly accessible by
the class in which they have been defined and any class that inherits
from this class.
EXAMPLE
Define a class Employee with member variables for an employee’s basic salary,
pension amount, medical aid amount and tax percentage. (The medical aid amount and
pension amount is what the employee pays – the company also contributes the same
amount towards the employee’s salary). The tax is calculated on the sum of the basic
salary, pension amount and medical aid amount.
Add appropriate constructors and accessors for class Employee and the following
member functions:

calcTax() calcGrossPay() calcDeductions()


calculate the amount that will calculate the gross pay
calculate how much should be
be deducted from the consisting of the basic salary + deducted from the
employee’s salary for tax the pension amount gross salary for pension and
(contributed by the company) + medical aid, i.e. the company’s
the medical aid amount contribution + the
(contributed by the company). member’s contribution.
SOLUTION: using separate compilation
Interface or header file Employee.h

#ifndef EMPLOYEE_H
#define EMPLOYEE_H #include <iostream>
using namespace std;
class Employee
{
public:
Employee();
~Employee();
Employee(double basic, double pension, double medical, double
tax);
double getBasic() const;
double getPension() const;
SOLUTION: using separate compilation
Interface or header file Employee.h (continued)

double getMedical() const;


double getTax() const;
double calcTax() const;
double calcGrossPay() const;
double calcDeductions() const;

protected:
double BasicSalary;
double PensionAmt; //the pension amount that the employee pays.
//The company adds the same amount.
double MedicalAmt; //the medical aid amount that the employee pays.

//The company adds the same amount

double TaxPercentage;
};
#endif
SOLUTION: using separate compilation
Employee.cpp
//Employee.cpp
#include "Employee.h"
#include <iostream>
using namespace std;

Employee::Employee()
{
BasicSalary = 0;
PensionAmt = 0;
MedicalAmt = 0;
TaxPercentage = 0.00;
}
SOLUTION: using separate compilation
Employee.cpp(continued)
Employee::Employee(double basic, double pension, double medical, double tax)
{
BasicSalary = basic;
PensionAmt = pension;
MedicalAmt = medical;
TaxPercentage = tax;
}
Employee::~Employee()
{
//destructor – do nothing
}
SOLUTION: using separate compilation
Employee.cpp(continued)
double Employee::getBasic() const
{
return BasicSalary;
}
double Employee::getPension() const
{
return PensionAmt;
}
}
double Employee::getTax() const
{
return TaxPercentage;
}
SOLUTION: using separate compilation
Employee.cpp(continued)

double Employee::calcTax() const


{
return TaxPercentage * (BasicSalary + PensionAmt +
MedicalAmt);
}
Implementation: main.cpp
A driver program to test the implementation of the class Employee:

 Use the overloaded constructor to instantiate an object of class


Employee.

 Use the accessor functions to display the values of the member variables
of the instantiated object.

 Calculate and display the net salary for an employee object.


SOLUTION: using separate compilation
Main.cpp

//test program
#include "Employee.h"
#include <iostream>
using namespace std;
int main()
{
Employee MrSmith(25110.00, 2350.00, 2400.00, 00.08);
cout.setf(ios::fixed);
cout.precision(2);
cout.setf(ios::showpoint);
cout << "An employee's salary details are as follows : " << endl <<
endl;
cout << "Basic salary : R" << MrSmith.getBasic() << endl;
SOLUTION: using separate compilation
Main.cpp (continued)

cout << "Pension amount : R" << MrSmith.getPension() << endl;


cout << "Medical aid amount : R" << MrSmith.getMedical() << endl;
cout << "% Tax paid : " << MrSmith.getTax() << endl;
cout << "An employee gets a net salary of R" <<
MrSmith.calcGrossPay() - MrSmith.calcTax() - MrSmith.calcDeductions()
<< endl;
return 0;
}
Inheritance: Deriving a Manager class
Derive and implement a class Manager from class Employee.
This class has an additional member variable, Allowance indicating the entertainment
allowance amount that a manager receives.
Class Manager has the following member functions:

Manager() getAllowance() setAllowance()


overloaded constructor for the Accessor for the Allowance Mutator for the Allowance
class Manager which will member variable. member variable.
invoke the base class
constructor.
calcTax()
override function calcTax() in Employee to include the
Display() entertainment allowance in the taxable amount when the tax
displays the salary details of a percentage is calculated. It should also override function
manager. calcGrossPay() to include the entertainment allowance.
SOLUTION: using separate compilation
Interface or header file Manager.h

Manager.h:
//Manager.h
#ifndef MANAGER_H
#define MANAGER_H
#include "Employee.h“
#include <iostream>

using namespace std;

class Manager : public Employee


{
public: Indicates inheritance
Manager();
~Manager();
SOLUTION: using separate compilation
Interface or header file Manager.h (continued)

double getAllowance() const; N.B. we do not redefine


void setAllowance(double a); methods in the base
double calcTax() const; class here.They are
double calcGrossPay() const; automatically available
void Display(); to this class.

private:
double Allowance;
};

#endif
SOLUTION: using separate compilation
Implementation file Manager.cpp
//Manager.cpp #include "Employee.h"
#include "Manager.h"
#include <iostream> using namespace std;

//default constructor Manager::Manager()


{
BasicSalary = 0;
PensionAmt = 0; Parent class member variables
MedicalAmt = 0;
TaxPercentage = 0.00;
Allowance = 0; child class member variable
}
SOLUTION: using separate compilation
Implementation file Manager.cpp (continued)
Parent class member variables
//overloaded constructor
Manager::Manager(double basic, double pension, double medical, double tax,

double allowance): child class member variable

Employee(basic, pension, medical, tax), Call to Parent class constructor with


parent class member variables
Allowance(allowance)
{} Initializing the child class
member variable

Manager::~Manager()
{
//destructor – do nothing
}
SOLUTION: using separate compilation
Implementation file Manager.cpp (continued)

//overloaded constructor
double Manager::getAllowance() const
{ Return the value of the child
return Allowance; class member variable

void Manager::setAllowance(double a)
Changing the value of the
{ child class member variable
Allowance = a;
}
SOLUTION: using separate compilation
Implementation file Manager.cpp (continued)

double Manager::calcTax() const


{
return (TaxPercentage * (BasicSalary + PensionAmt + MedicalAmt +

Allowance));
}

double Manager::calcGrossPay() const


{
return (BasicSalary + PensionAmt + MedicalAmt + Allowance);
}
SOLUTION: using separate compilation
Implementation file Manager.cpp (continued)

void Manager::Display()
{
cout.setf(ios::showpoint);
cout.setf(ios::fixed);
cout << "Manager's salary details:" << endl << endl;
cout << "Basic Salary: R" << BasicSalary << endl;
cout << "Pension contribution: R" << PensionAmt << endl;
cout << "Medical Aid contribution amount: R" << MedicalAmt <<
endl;
cout << "Entertainment allowance: R" << Allowance << endl; cout
<< "% tax payable: " << TaxPercentage << endl;
}
Implementation: main.cpp
 Testing the class Manager derived from class Employee in a
driver program.
 Note that the implementation of the parent class (Employee.cpp)
must be included as part of the project files, and the header file
Employee.h must be included in the .h and .cpp files for class
Manager with the #include "Employee.h" directive.
 N.B: the #include "Employee.h" directive should not be included
in the test implementation file main.cpp.
 Employee.h and Employee.cpp need to be in the same folder as
the other files for class Manager.

11-40
Implementation: main.cpp
main.cpp:

//test program
#include "Manager.h“
#include <iostream>
using namespace std;

int main()
{
Manager theManager (60560.00, 5500.00, 2800.00, 00.14, 2100.00);
cout.setf(ios::fixed);
cout.precision(2);

11-41
Implementation: main.cpp
main.cpp (continued)
theManager.Display();
cout.setf(ios::showpoint);
cout << "A manager gets a net salary of R"
<<theManager.calcGrossPay() – theManager.calcTax()
- theManager.calcDeductions() << endl;

return 0;
}

11-42

You might also like