0% found this document useful (0 votes)
37 views20 pages

Lec10. Inheritance

The document discusses inheritance in object-oriented programming using the example of an Employee class and derived HourlyEmployee and SalariedEmployee classes. The Employee class acts as a base class containing common properties and functions, while the derived classes extend it with additional properties and specialized implementations of functions like printCheck.

Uploaded by

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

Lec10. Inheritance

The document discusses inheritance in object-oriented programming using the example of an Employee class and derived HourlyEmployee and SalariedEmployee classes. The Employee class acts as a base class containing common properties and functions, while the derived classes extend it with additional properties and specialized implementations of functions like printCheck.

Uploaded by

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

Chapter 14

Inheritance

Copyright © 2017 Pearson Education, Ltd.


All rights reserved.
Introduction to Inheritance
• Object-oriented programming
– Powerful programming technique
– Provides abstraction dimension called inheritance
• General form of class is defined
– Specialized versions then inherit properties of general class
– And add to it/modify it’s functionality for it’s appropriate use
• Inheritance basics: new class inherited from another class
– Base class: "General" class from which others derive. Also called parent class
– Derived class: New class that is a child of parent or base class
• Automatically has base class’s:
– Member variables
– Member functions
• Can then add additional or redefine existing member functions and variables

14-2
Derived Classes Through Example
• Class of "Employees" Employees
is a
– Composed of:
Salaried Hourly
• Salaried employees
Employees Employees
• Hourly employees
– No one is just an "employee“. Each is "subset" of employees
• Another might be those paid fixed wage each month or week
• General concept of employee is helpful!
– All have names
– All have social security numbers
– Associated functions for these "basics" are same among all employees
• So "general" class can contain all these "things" about employees

14-3
//This is the interface for class Employee intended to be used as base class to derive classes for different kinds of
// employees. Many members of "employee" class apply to all types of employees. We won’t have "objects" of this
// class
#ifndef EMPLOYEE_H
#define EMPLOYEE_H Employee Class
#include <string>
using std::string; employee.h
class Employee {
public:
Employee( );
Employee( const string& theName, const string& theSsn);
//Accessor functions
string getName( ) const;
string getSsn( ) const;
double getNetPay( ) const;
void printCheck( ) const;
//Mutator functions
void setName( const string& newName);
void setSsn( const string& newSsn);
void setNetPay( double newNetPay);
private:
string name;
string ssn;
double netPay;
};
#endif //EMPLOYEE_H
14-4
//Implementation for the Base Class Employee.
#include <string> Employee Class
#include <cstdlib>
#include <iostream>
employee.cpp
#include "employee.h"
using namespace std;
Employee::Employee( ) : name("No name yet"), ssn("No number yet"), netPay(0){}
Employee::Employee( const string& theName, const string& theNumber)
: name(theName), ssn(theNumber), netPay(0){}
string Employee::getName( ) const {
return name;
}
string Employee::getSsn( ) const{
return ssn;
}
double Employee::getNetPay( ) const {
return netPay;
}
void Employee::setName( const string& newName){
name = newName;
}
void Employee::setSsn( const string& newSsn) {
ssn = newSsn;
}
void Employee::setNetPay ( double newNetPay){
netPay = newNetPay;
}
void Employee::printCheck( ) const {
cout << "\nERROR: printCheck FUNCTION CALLED FOR AN \n"
<< "UNDIFFERENTIATED EMPLOYEE. Aborting the program.\n"
exit(1); 14-5
}
Employee Class
• Many members of "employee" class apply to all types of employees
– Accessor functions
– Mutator functions
– Most data items: SSN, Name, Pay
• Derived classes from base class Employee :
– Automatically have "inherit" member variables and member functions
– Can then redefine existing members and/or add new members
• Consider printCheck() function:
– Will always be "redefined" in derived classes, so different employee types can
have different checks
– Makes no sense really for "undifferentiated“ employee
– So function printCheck()in Employee class says just that
• Error message stating "printCheck called for undifferentiated employee!!
Aborting…" 14-6
// Interface for the Derived Class HourlyEmployee
#ifndef HOURLYEMPLOYEE_H
#define HOURLYEMPLOYEE_H
#include <string> HourlyEmployee Class
#include "employee.h " HourlyEmployee.h
using namespace std;
class HourlyEmployee : public Employee {
public:
HourlyEmployee( );
HourlyEmployee( const string& theName, const string& theSsn,
double theWageRate, double theHours);
void setRate( double newWageRate);
double getRate( ) const;
void setHours( double hoursWorked);
double getHours( ) const;
void printCheck( );
List only the declaration of an
private
inherited member function if you
double wageRate;
want to change the definition of
double hours;
the function.
};
#endif //HOURLYEMPLOYEE_H

14-7 14-7
// Interface for the Derived Class SalariedEmployee
#ifndef SALARIEDEMPLOYEE_H
#define SALARIEDMPLOYEE_H
#include <string> SalariedEmployee Class
#include "employee.h" SalariedEmployee.h
using namespace std;

class SalariedEmployee : public Employee {


public:
SalariedEmployee( );
SalariedEmployee( const string& theName, const string& theSsn,
double salary);
double getSalary( ) const;
void setSalary( double newSalary);
void printCheck( );
private
double salary; //weekly
};
#endif //SALARIEDEMPLOYEE_H

14-8 14-8
//This is the implementation for the class HourlyEmployee
#include <string>
#include <iostream> HourlyEmployee Class
#include "hourlyemployee.h"
HourlyEmployee.cpp
using namespace std;

HourlyEmployee::HourlyEmployee( ) :Employee(),wageRate(0), hours(0) {}

HourlyEmployee::HourlyEmployee( const string& theName, const string& theNumber,


double theWageRate, double theHours)
:Employee(theName, theNumber), wageRate(theWageRate), hours(theHours) {}

void HourlyEmployee::setRate( double newWageRate) {wageRate = newWageRate;}

double HourlyEmployee::getRate( ) const { return wageRate;}

void HourlyEmployee::setHours( double hoursWorked) {hours = hoursWorked;}

double HourlyEmployee::getHours( ) const { return hours;} We have chosen to set netPay


as part of the printCheck
void HourlyEmployee::printCheck( ) { function because that is
setNetPay(hours * wageRate); when it is used. In any event,
cout << "\n__________________________________________\n"; this is an accounting question,
cout << "Pay to the order of " << getName( ) << endl; not a programming question.
cout << "The sum of " << getNetPay( ) << " Dollars\n"; But, note that C++ allows us
cout << "__________________________________________\n";
to drop the const on the
cout << "Check Stub: NOT NEGOTIABLE\n";
function printCheck when
cout << "Employee Number: " << getSsn( ) << endl;
cout << "Hourly Employee. \nHours worked: " << hours
we redefine it in a derived
<< " Rate: " << wageRate << " Pay: " class.
<< getNetPay( ) << endl;
cout << "__________________________________________\n"; 14-9 14-9
}
//This is the implementation for the class salariedEmployee
#include <string>
#include <iostream>
#include "salariedemployee.h"
salariedEmployeeClass
salariedEmployee.cpp
using namespace std;

SalariedEmployee::SalariedEmployee( ) :Employee(), salary(0){}

SalariedEmployee::SalariedEmployee( const string& theName,


const string& theNumber, double salary)
:Employee(theName, theNumber), salary(salary){}

double SalariedEmployee::getSalary( ) const {return salary;}

void SalariedEmployee::setSalary( double newSalary) { salary = newSalary;}

void SalariedEmployee::printCheck( ){
setNetPay(salary);
cout << "\n__________________________________________\n";
cout << "Pay to the order of " << getName( ) << endl;
cout << "The sum of " << getNetPay( ) << " Dollars\n";
cout << "__________________________________________\n";
cout << "Check Stub: NOT NEGOTIABLE\n";
cout << "Employee Number: " << getSsn( ) << endl;
cout << "Salaried Employee. Regular Pay:"
<< getNetPay( ) << endl;
cout << "__________________________________________\n";
}
14-10 14-10
#include <iostream>
#include "hourlyemployee.h"
#include "salariedemployee.h" tester.cpp
using std::cout;
using std::endl;

int main( ){
HourlyEmployee joe;
joe.setName("Mighty Joe");
joe.setSsn("123-45-6789");
joe.setRate(20.50);
joe.setHours(40);
cout << "Check for " << joe.getName( )
<< " for " << joe.getHours( ) << " hours.\n";
joe.printCheck( );
cout << endl;
SalariedEmployee boss("Mr. Big Shot", "987-65-4321", 10500.50);
cout << "Check for " << boss.getName( ) << endl;
boss.printCheck( );
return 0;
}

14-11 14-11
HourlyEmployee Class Interface
• Note definition begins same as any other
– #ifndef structure, then includes required libraries and employee.h!
– And, the heading: class HourlyEmployee : public Employee{
• Specifies "publicly inherited" from Employee class

• Derived class interface only lists new or "to be redefined" members


– Since all others inherited are already defined i.e.: ssn, name, etc.
– HourlyEmployee adds:
• Constructors
• wageRate, hours member variables
• setRate(), getRate(), setHours(), getHours() member functions
– HourlyEmployee redefines:
• printCheck() member function
• This "overrides" the printCheck() function implementation from Employee
class 14-12
Constructors in Derived Classes
• Base class constructors are NOT inherited in derived classes!
– But they can be invoked within derived class constructor
• Base class constructor must initialize all base class member
variables
– Those inherited by derived class
– So derived class constructor simply calls it
• "First" thing derived class constructor does
• Consider syntax for HourlyEmployee constructor:

HourlyEmployee::HourlyEmployee(string theName, string theNumber,


double theWageRate, double theHours)
: Employee(theName, theNumber),
wageRate(theWageRate), hours(theHours)
{
//Deliberately empty
}

• Portion after is "initialization section“ includes invocation of Employee


constructor
14-13
Another HourlyEmployee Constructor
• A second constructor:
HourlyEmployee::HourlyEmployee(): Employee(), wageRate(0), hours(0)
{
//Deliberately empty
}

• Default version of base class constructor is called (no arguments)


• Derived class constructor should always invoke one of the base
class’s constructors
– If you do not: Default base class constructor automatically called
• Equivalent constructor definition:

HourlyEmployee::HourlyEmployee(): wageRate(0), hours(0)


{ }

14-14
Pitfall: Base Class Private Member Data and Functions
• Derived class "inherits" private member variables
– But still cannot directly access them
– Not even through derived class member functions!
– Private member variables can ONLY be accessed "by name" in member
functions of the class they’re defined in
• Same holds for base class private member functions
– Cannot be accessed outside interface and implementation of base class
– Not even in derived class member function definitions

14-15
The protected: Qualifier
• you cannot access a base class private member variable or private
member from a derived class
• Qualifier protected
– Allows access "by name" base class member variables and functions in
derived class
• But nowhere else
• Still no access "by name" in other classes

– In class where it’s defined  acts like private


– Considered "protected" in derived class
• To allow future derivations

– Many feel this "violates" information hiding

14-16
Redefinition of Member Functions
• Implementation of derived class will:
– Define new member functions
– Redefine inherited functions as declared
• Redefining vs. Overloading
– Very different!
– Redefining in derived class: SAME parameter list
• Essentially "re-writes" same function
– Overloading: Different parameter list
• Defined "new" function that takes different parameters
• Overloaded functions must have different signatures
• Function’s Signature is:
– Function’s name
– Sequence of types in parameter list: order, number, types
• Signature does NOT include: Return type, const keyword, &
14-17
Accessing Redefined Base Function
• When redefined in derived class, base class’s definition not "lost"
• We can specify it is used:
Employee JaneE;
HourlyEmployee SallyH;
JaneE.printCheck(); // calls Employee’s printCheck function
SallyH.printCheck(); // calls HourlyEmployee printCheck function
SallyH.Employee::printCheck(); // Calls Employee’s printCheck function!

• Not typical, but useful sometimes


• All "normal" functions in base class are inherited in derived class
– Exceptions:
• Constructors (we’ve seen)
• Destructors
• Copy constructor: But if not defined in derived class, C++ generates "default" one
– default copy constructor copies contents and does not work correctly with pointers or
dynamic allocation
» Recall need to define one for pointers!
• Assignment operator: If not defined  default
14-18
Assignment Operators and Copy Constructors
• Overloaded = operators and copy constructors are NOT inherited
– But can be used in derived class definitions (Typically MUST be used!)
• Similar to how derived class constructor invokes base class constructor

• Examples: given "Derived" is derived from "Base":


– Calling = operator from base class takes care of all inherited member variables
– Would then set new variables from derived class…

Derived& Derived::operator =(const Derived & rightSide){


Base::operator =(rightSide); //This takes care of the inherited member variables and their data

}
Derived::Derived(const Derived& Object): Base(Object), …
{…}

– Similarly, invocation of base copy constructor sets inherited member variables


of derived class object being created
– Note Object is of type Derived; but it’s also of type Base, so argument is valid
14-19
Destructors in Derived Classes
• If base class destructor functions correctly
– Easy to write derived class destructor
• When derived class destructor is invoked:
– Automatically calls base class destructor!
• So derived class destructors need only be concerned with derived
class variables
– And any data they "point" to
– Base class destructor handles inherited data automatically

14-20

You might also like