Lec10. Inheritance
Lec10. Inheritance
Lec10. Inheritance
Inheritance
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;
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;
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
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
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!
14-20