Modern object-oriented (OO) languages provide 3 capabilities:
which can improve the design, structure and reusability of code.
Here, we'll explore how the object-oriented (OO) programming capability known as inheritance can be used in C++.
All code examples are available for download.
Real-world entities, like employees, are naturally described by both data and functionality.
We will represent different types of employees:
For these employees, we'll store data, like their:
And...we'll require some functionality, like being able to:
Employee class:Object-oriented languages typically provide a natural way to treat data and functionality as a single entity. In C++, we do so by creating a class.
Here is a class definition for a generic Employee:
class Employee {
public:
  Employee(string theName, float thePayRate);
  string getName() const;
  float getPayRate() const;
  float pay(float hoursWorked) const;
protected:
  string name;
  float payRate;
};
The class consists of:
Definitions for each of the methods follow:
Employee::Employee(string theName, float thePayRate)
{
  name = theName;
  payRate = thePayRate;
}
string Employee::getName() const
{
  return name;
}
float Employee::getPayRate() const
{
  return payRate;
}
float Employee::pay(float hoursWorked) const
{
  return hoursWorked * payRate;
}
Note that the payRate is used as an hourly wage.
#include "employee.h"
...
  Employee empl("John Burke", 25.0);
  // Print out name and pay (based on 40 hours work).
  cout << "Name: " << empl.getName() << endl;
  cout << "Pay: " << empl.pay(40.0) << endl;
Manager class:In the real world, we don't view everything as unique; we often view something as being like something else but with differences or additions.
Managers are like regular employees; however, there might be differences. For example, they might be paid by a salary.
Our first attempt to write a class for a manager gives the following class definition:
class Manager {
public:
  Manager(string theName,
          float thePayRate,
          bool isSalaried);
  string getName() const;
  float getPayRate() const;
  bool getSalaried() const;
  float pay(float hoursWorked) const;
protected:
  string name;
  float payRate;
  bool salaried;
};
Employee in that it has an
additional field (salaried) and method
(getSalaried()).
The method definitions for class Manager do not differ
much from Employee either:
Manager::Manager(string theName,
                 float thePayRate,
                 bool isSalaried)
{
  name = theName;
  payRate = thePayRate;
  salaried = isSalaried;
}
string Manager::getName() const
{
  return name;
}
float Manager::getPayRate() const
{
  return payRate;
}
bool Manager::getSalaried() const
{
  return salaried;
}
float Manager::pay(float hoursWorked) const
{
  if (salaried)
    return payRate;
  /* else */
  return hoursWorked * payRate;
}
They add very little new code to what was
written in  
Compared to  
 
 
 
Finally, the  
 
 
We have done unnecessary work to create  
We can fix this using the OO concept of inheritance.  If we
let a manager inherit from an employee, then it will get all the data
and functionality of an employee.  We can then add any new data and
methods needed for a manager and redefine any methods that
differ for a manager.
 
Here, we show a new implementation of  
The line:
 
 
The only things included in the class definition are:
 
 
Like this new class definition, the method definitions are also simplified:
 
 
For the  
that does some of the same work as the  
The only way to pass values to  
A member initialization list follows a constructor's parameter list.
It consists of a colon ( 
 
Without doing so,  
For those using an object (versus those defining a
class), "protected" works like the "private" access specifier:
 
Note that when we call  
 
Remember, it inherited all the data and methods of an
 
 
Since we now have one class that inherits from another, we have the
beginnings of a class hierarchy:
 
 
If needed, this hierarchy could be extended to include more classes.
 
 
 
 
Which hierarchy would we choose?
 
If a supervisor is viewed as part of management, then choice a) is
probably your answer.  Nonetheless, this is a decision not to be taken
lightly.  How one designs the inheritance hierarchy greatly affects
what you can do with those classes later.
 
 
Take the code we've provided for the  
Add methods to the classes named:
 
 
that let users change the corresponding fields.  Take advantage of
the inheritance relationship between  
Write a  
 
What class should  
Your code should compile and run correctly with the test program Employee.
Employee, in Manager...
getName() and getPayRate()
are identical to those in Employee.
getSalaried() is new.
pay() method work differently.
Nonetheless, they do some of the same work as their counterparts in the
Employee class.
payRate has 2 possible uses in the
Manager class...
If the manager is salaried, 
float Manager::pay(float hoursWorked) const
{
  if (salaried)
    return payRate;
  /* else */
  return hoursWorked * payRate;
}
payRate is the fixed rate for
the pay period; otherwise, it represents an hourly rate, just like it
does for a regular employee.
Such a Manager can be used in a similar manner to an
Employee:
#include "manager0.h"
...
  Manager mgr("Jan Kovacs", 1200.0, true);
  // Print out name and pay (based on 40 hours work).
  cout << "Name: " << mgr.getName() << endl;
  cout << "Pay: " << mgr.pay(40.0) << endl;
Manager, which is
similar to (and really is a "kind of") Employee.
Manager that
inherits from Employee:
#include "employee.h"
class Manager : public Employee {
public:
  Manager(string theName,
          float thePayRate,
          bool isSalaried);
  bool getSalaried() const;
  float pay(float hoursWorked) const;
protected:
  bool salaried;
};
causes 
class Manager : public Employee {
Manager to inherit all the data and methods of
Employee.
Note:
Although other access specifiers (besides "public") can be used with
inheritance, we will only discuss public inheritance here.
salaried,
getSalaried(),
pay() (which is redefined in
Manager).
There are some things to note about these method definitions...
Manager::Manager(string theName,
                 float thePayRate,
                 bool isSalaried)
  : Employee(theName, thePayRate)
{
  salaried = isSalaried;
}
bool Manager::getSalaried() const
{
  return salaried;
}
float Manager::pay(float hoursWorked) const
{
  if (salaried)
    return payRate;
  /* else */
  return Employee::pay(hoursWorked);
}
Member initialization list
For constructors that require arguments, you must write a new constructor
for each class.
Note:
Classes don't explicitly inherit constructors.
Manager class, we needed a constructor:
Manager::Manager(string theName,
                 float thePayRate,
                 bool isSalaried)
  : Employee(theName, thePayRate)
{
  salaried = isSalaried;
}
Employee
constructor.  To do so, we reused Employee's
constructor.
Employee's constructor in
this context is via a member initialization list.
:) and a comma-separated list of
inherited class names (and values to be passed to their constructors).
Note:
The member initialization list can also be used to pass values
to constructors of data members.  For example,
class SomeClass {
public:
  SomeClass();
private:
  const int SIZE;
  AnotherClass data;
};
SomeClass::SomeClass() : SIZE(10), data("foo")
{
  // more initialization code
}
SIZE could not be initialized (because
its constant) and data's default constructor (if it has one)
would be used.
The 
Methods of protected access specifierManager have access to payRate
because it was declared in
Employee as "protected":
I.e., classes that inherit a "protected" field or method can access them.
float Manager::pay(float hoursWorked) const
{
  if (salaried)
    return payRate;  // Yeah, I can use!
  ...
}
I.e., the "protected" fields remain inaccessible just as they were in
Manager mgr;
mgr.payRate;  // Doesn't work!
Employee:
Employee empl;
empl.payRate;  // Doesn't work!
Calling inherited methods
The pay() method of Manager uses a different
calculation if the manager is salaried.  Otherwise, it makes the
same calculation as a regular Employee:
We reused the 
float Manager::pay(float hoursWorked) const
{
  if (salaried)
    return payRate;
  /* else */
  return Employee::pay(hoursWorked);
}
pay() method of
Employee to define the pay() method of
Manager.
Employee's pay()
method:
we must explicitly specify the class from which it comes (i.e., from
which it was inherited).  Without doing so, we'd have an infinite
recursive call:
Employee::pay(hoursWorked);
float Manager::pay(float hoursWorked) const
{
  ...
  return pay(hoursWorked);  // Calls Manager::pay()!
}
This new Manager class can be used just like our first attempt:
Excitingly, it has methods from 
#include "manager.h"
...
  Manager mgr("Jan Kovacs", 1200.0, true);
  // Print out name and pay (based on 40 hours work).
  cout << "Name: " << mgr.getName() << endl;
  cout << "Pay: " << mgr.pay(40.0) << endl;
Employee, like
getName(), that we did not declare or define in
Manager...
Employee!  Thus, we have reused our definition of
an employee to simplify defining a manager.
We say that 
Employee
   |
Manager
Employee is the base class and
Manager is a derived class of Employee.
Note:
Alternatively, we may call Employee the superclass
and Manager the subclass.
Adding a Supervisor
To add another type of employee, such as a supervisor, a new class
can be created.  Two choices of where to place a Supervisor
class in the hierarchy are:
a) Employee	 b) Employee
      |		     /    \
   Manager	Manager  Supervisor
      |
  Supervisor
The Supervisor class directly inherits from
Manager and indirectly inherits from
Employee.
Supervisor directly inherits from
Employee.
Aside:
We can say that Supervisor inherits from
Employee when there is either a direct or indirect inheritance
relationship.
Employee class (employee.h and employee.cpp) and the
Manager class (manager.h and manager.cpp).
setName()
setPayRate()
setSalaried()
Employee
and Manager--you only need add each of those methods to
1 class.
Supervisor class.  A supervisor is
responsible for employees in a specific department and must:
getDept() and setDept() methods
to access the department field.
Supervisor inherit from?
empltest.cpp.