Inheritance - Chapter 11
Inheritance - Chapter 11
Kristina Shroyer
1
Chapter Objectives
In this chapter you’ll learn:
n To create classes by inheriting from existing classes.
n How inheritance promotes software reuse.
n The notions of base classes and derived classes and the
relationships between them.
n The protected member access specifier.
n The use of constructors and destructors in inheritance
hierarchies.
n The differences between public, protected and
private inheritance.
n The use of inheritance to customize existing software.
2
Inheritance – The Is-A Relation
l Another important relationship between classes in a program is the
Is-A relation which is the relationship of inheritance
3
Inheritance – The Is-A Relation
l When one object is a specialized version of another
object there is an Is-A relationship between them
n A poodle is a dog
n A car is a vehicle
n A rectangle is a shape
4
Inheritance – The Is-A Relation
l Why is Inheritance useful?
n Software reusability
♦ Saves time during program development
♦ Encourages the reuse of proven, debugged, high quality software
l Increases the likelihood that a system will be implemented effectively
n Create new class from existing class
♦ Absorb existing class’s data and behaviors
♦ Enhance and/or extend with new capabilities
5
Inheritance – The Is-A Relation
l This is a UML lite visualization of inheritance
n Multiple inheritance
♦ Inherits from multiple base classes
l Base classes possibly unrelated
♦ This chapter focuses on single inheritance
l Multiple inheritance is one of those "special cases" (like globals) that is
general discouraged so I like to stay away from that in the main discussion –
if time at the end of the class we can look into it more
8
Inheritance Hierarchy Example
l Inheritance Hierarch for University
Community Members
9
Types of Inheritance - Intro
l Three types of inheritance
n public
10
Inheritance – Introduction cont.
l Abstraction
n Focuses on commonalities among objects in system
n So with abstraction and object oriented programming we
focus on the relationships between objects
♦ We focus on the commonalities rather than the special cases
11
Inheritance – Introduction cont.
l A derived class can access the non-private members
of its base class
n Any base class members that should not be accessible to the
member class functions of the derived class should be made
private
12
Base Classes and Derived Classes
l Base classes and derived classes
l Object of one class “is an” object of another class
n Example: Rectangle is a quadrilateral
♦ Class Rectangle inherits from class Quadrilateral
l Quadrilateral is the base class
l Rectangle is the derived class
13
Inheritance Examples
14
Base Classes and Derived Classes
l Inheritance hierarchy
n Inheritance relationships form a tree-like hierarchy structure
n Each class becomes
♦ Base class
l Supplies data/behaviors to other classes
AND/OR
♦ Derived class
l Inherits data/behaviors from other classes
15
Inheritance Hierarchy Examples
l Each arrow represents an is a relationship.
n Starting from the bottom of the diagram you can follow the arrows and apply the is a
relationship to the topmost base class
n So an AdministratorTeacher is a Administrator, is a Faculty member, is an Employee and
is a Community member follow the path
n An Administrator Teacher is also a Teacher
17
Specifying public Inheritance
l class Student : public Person
18
public Inheritance
l public inheritance
n Specify with:
class TwoDimensionalShape : public Shape
♦ Class TwoDimensionalShape inherits from class Shape
l friend functions
n ARE NOT INHERITED
19
Protected Members
l Up until now we have used two access specifications when we
defined classes: private and public
n C++ provides a third class access specification: protected
20
Protected Members/Redefined base class
member functions
l Derived-class members
n Refer to public and protected members of base class by
♦ Simply using the public or protected member names directly or by going
through member functions (going through member functions is often better
design as we will discuss so keep that in mind)
21
Examples Base Class & Derived Class
l We're going to look at a series of examples involving the
following two classes:
♦ CommissionEmployee
l First name, last name, SSN, commission rate, gross sale amount
l these employees are paid solely on commissions
♦ BasePlusCommissionEmployee
l First name, last name, SSN, commission rate, gross sale amount
l And also: base salary
l these employees get a base salary plus commissions
22
CommissionEmployee class
l Example 1
n So first we'll create this class on it's own with no inheritance
involved
23
1 // Fig. 12.4: CommissionEmployee.h
2 // CommissionEmployee class definition represents a commission employee.
3 #ifndef COMMISSION_H
4 #define COMMISSION_H
5
6 #include <string> // C++ standard string class Example 1
7 using std::string;
8 Commission
9 class CommissionEmployee Employee.h
10 {
11 public: (1 of 2)
12 CommissionEmployee( const string &, const string &, const string &,
13 double = 0.0, double = 0.0 );
Class CommissionEmployee constructor
14
15 void setFirstName( const string & ); // set first name
16 string getFirstName() const; // return first name
17
18 void setLastName( const string & ); // set last name
19 string getLastName() const; // return last name
20
21 void setSocialSecurityNumber( const string & ); // set SSN
22 string getSocialSecurityNumber() const; // return SSN
23
24 void setGrossSales( double ); // set gross sales amount
25 double getGrossSales() const; // return gross sales amount
26
27 void setCommissionRate( double ); // set commission rate (percentage)
28 double getCommissionRate() const; // return commission rate
24
29
30 double earnings() const; // calculate earnings
31 void print() const; // print CommissionEmployee object
32 private:
33 string firstName;
34 string lastName; Declare private Example 1
35 string socialSecurityNumber; data members
36 double grossSales; // gross weekly sales
Commission
37 double commissionRate; // commission percentage
Employee.h
38 }; // end class CommissionEmployee
39
(2 of 2)
40 #endif
25
1 // Fig. 12.5: CommissionEmployee.cpp
2 // Class CommissionEmployee member-function definitions.
3 #include <iostream>
4 using std::cout;
5
6 #include "CommissionEmployee.h" // CommissionEmployee class definition
7
8 // constructor
9 CommissionEmployee::CommissionEmployee(
10 const string &first, const string &last, const string &ssn,
11 double sales, double rate )
12 {
13 firstName = first; // should validate Initialize data members
14 lastName = last; // should validate
15 socialSecurityNumber = ssn; // should validate
16 setGrossSales( sales ); // validate and store gross sales Example 1
17 setCommissionRate( rate ); // validate and store commission rate
18 } // end CommissionEmployee constructor Commission
19 Employee.cpp
20 // set first name
21 void CommissionEmployee::setFirstName( const string &first ) (1 of 4)
22 {
23 firstName = first; // should validate
24 } // end function setFirstName
25
26 // return first name
27 string CommissionEmployee::getFirstName() const
28 {
29 return firstName;
30 } // end function getFirstName
26
31
32 // set last name
33 void CommissionEmployee::setLastName( const string &last )
34 {
35 lastName = last; // should validate
36 } // end function setLastName
37
38 // return last name
39 string CommissionEmployee::getLastName() const Example 1
40 {
41 return lastName; Commission
42 } // end function getLastName Employee.cpp
43
44 // set social security number (2 of 4)
45 void CommissionEmployee::setSocialSecurityNumber( const string &ssn )
46 {
47 socialSecurityNumber = ssn; // should validate
48 } // end function setSocialSecurityNumber
49
50 // return social security number
51 string CommissionEmployee::getSocialSecurityNumber() const
52 {
53 return socialSecurityNumber;
Function setGrossSales
54 } // end function getSocialSecurityNumber
55 validates gross sales amount
56 // set gross sales amount
57 void CommissionEmployee::setGrossSales( double sales )
58 {
59 grossSales = ( sales < 0.0 ) ? 0.0 : sales;
60 } // end function setGrossSales
27
61
62 // return gross sales amount
63 double CommissionEmployee::getGrossSales() const
64 {
65 return grossSales;
66 } // end function getGrossSales
Function setCommissionRate
67 validates commission rate
68 // set commission rate
69 void CommissionEmployee::setCommissionRate( double rate )
70 { Example 1
71 commissionRate = ( rate > 0.0 && rate < 1.0 ) ? rate : 0.0;
Commission
72 } // end function setCommissionRate Employee.cpp
73
74 // return commission rate (3 of 4)
75 double CommissionEmployee::getCommissionRate() const
76 {
77 return commissionRate;
78 } // end function getCommissionRate
28
79
80 // calculate earnings
81 double CommissionEmployee::earnings() const
82 {
Function earnings
83 return commissionRate * grossSales; calculates earnings
84 } // end function earnings
85
86 // print CommissionEmployee object
87 void CommissionEmployee::print() const
88 {
Function print displays
89 cout << "commission employee: " << firstName << ' ' << CommissionEmployee object
lastName
90 << "\nsocial security number: " << socialSecurityNumber
91 << "\ngross sales: " << grossSales Example 1
92 << "\ncommission rate: " << commissionRate;
Commission
93 } // end function print
Employee.cpp
(4 of 4)
29
1 // Fig. 12.6: fig12_06.cpp
2 // Testing class CommissionEmployee.
3 #include <iostream>
4 using std::cout;
5 using std::endl;
6 using std::fixed;
7 Example 1
8 #include <iomanip>
9 using std::setprecision; testCommEmp.cpp
10
11 #include "CommissionEmployee.h" // CommissionEmployee class definition (1 of 2)
12
13 int main()
14 { Instantiate CommissionEmployee object
15 // instantiate a CommissionEmployee object
16 CommissionEmployee employee(
17 "Sue", "Jones", "222-22-2222", 10000, .06 );
18
19 // set floating-point output formatting
20 cout << fixed << setprecision( 2 );
21
22 // get commission employee data
23 cout << "Employee information obtained by get functions: \n"
24 << "\nFirst name is " << employee.getFirstName()
25 << "\nLast name is " << employee.getLastName() Use CommissionEmployee’s
26 << "\nSocial security number is " get functions to retrieve the
27 << employee.getSocialSecurityNumber()
object’s instance variable values
28 << "\nGross sales is " << employee.getGrossSales()
29 << "\nCommission rate is " << employee.getCommissionRate() << endl;
30
30
31 employee.setGrossSales( 8000 ); // set gross sales
32 employee.setCommissionRate( .1 ); // set commission rate
33
34
Use CommissionEmployee’s set functions
cout << "\nUpdated employee information output by print function: \n"
35 << endl; to change the object’s instance variable values
36 employee.print(); // display the new employee information
37 Call object’s print function to
38 // display the employee's earnings display employee information
39 cout << "\n\nEmployee's earnings: $" << employee.earnings() << endl;
40
41 return 0; Call object’s earnings
42 } // end main
function to calculate earnings
Employee information obtained by get functions:
31
BaseCommissionEmployee class
l Example 2
n Now we're going to create a completely independent
BaseCommissionEmployee class to show why
inheritance is better for certain examples like this
n As we look at it note all the similarities between this class
and the CommissionEmployee class
l Class BasePlusCommissionEmployee
n Much of the code is similar to CommissionEmployee
♦ private data members
♦ public methods
♦ constructor
n Additions
♦ private data member baseSalary
♦ Methods setBaseSalary and getBaseSalary
32
1 // Fig. 12.7: BasePlusCommissionEmployee.h
2 // BasePlusCommissionEmployee class definition represents an employee
3 // that receives a base salary in addition to commission.
4 #ifndef BASEPLUS_H
5 #define BASEPLUS_H
6
7
8
#include <string> // C++ standard string class
using std::string;
Example 2
9 BasePlus
10 class BasePlusCommissionEmployee Commission
11 { Employee.h
12 public:
13 BasePlusCommissionEmployee( const string &, const string &, (1 of 2)
14 const string &, double = 0.0, double = 0.0, double = 0.0 );
15
16 void setFirstName( const string & ); // set first name Constructor takes one more argument,
17 string getFirstName() const; // return first name
which specifies the base salary
18
19 void setLastName( const string & ); // set last name
20 string getLastName() const; // return last name
21
22 void setSocialSecurityNumber( const string & ); // set SSN
23 string getSocialSecurityNumber() const; // return SSN
24
25 void setGrossSales( double ); // set gross sales amount
26 double getGrossSales() const; // return gross sales amount
27
28 void setCommissionRate( double ); // set commission rate
29 double getCommissionRate() const; // return commission rate
33
30
31 void setBaseSalary( double ); // set base salary Define get and set functions for
32 double getBaseSalary() const; // return base salary data member baseSalary
33
34 double earnings() const; // calculate earnings
35 void print() const; // print BasePlusCommissionEmployee object
36 private: Example 2
37 string firstName; BasePlus
38 string lastName; Commission
39 string socialSecurityNumber; Employee.h
40 double grossSales; // gross weekly sales
41 double commissionRate; // commission percentage (2 of 2)
42 double baseSalary; // base salary
43 }; // end class BasePlusCommissionEmployee Add data member baseSalary
44
45 #endif
34
1 // Fig. 12.8: BasePlusCommissionEmployee.cpp
2 // Class BasePlusCommissionEmployee member-function definitions.
3 #include <iostream>
4 using std::cout;
5 Example 2
6 // BasePlusCommissionEmployee class definition BasePlus
7 #include "BasePlusCommissionEmployee.h" Commission
8 Employee.cpp
9 // constructor
10 BasePlusCommissionEmployee::BasePlusCommissionEmployee( (1 of 4)
11 const string &first, const string &last, const string &ssn,
12 double sales, double rate, double salary )
13 { Constructor takes one more argument,
14 firstName = first; // should validate which specifies the base salary
15 lastName = last; // should validate
16 socialSecurityNumber = ssn; // should validate
17 setGrossSales( sales ); // validate and store gross sales
18 setCommissionRate( rate ); // validate and store commission rate
19 setBaseSalary( salary ); // validate and store base salary
20 } // end BasePlusCommissionEmployee constructor
21 Use function setBaseSalary to validate data
22 // set first name
23 void BasePlusCommissionEmployee::setFirstName( const string &first )
24 {
25 firstName = first; // should validate
26 } // end function setFirstName
35
27
28 // return first name
29 string BasePlusCommissionEmployee::getFirstName() const
30 {
31 return firstName;
32 } // end function getFirstName
Example 2
33 BasePlus
34 // set last name Commission
35 void BasePlusCommissionEmployee::setLastName( const string &last )
Employee.cpp
36 {
37 lastName = last; // should validate
(2 of 4)
38 } // end function setLastName
39
40 // return last name
41 string BasePlusCommissionEmployee::getLastName() const
42 {
43 return lastName;
44 } // end function getLastName
45
46 // set social security number
47 void BasePlusCommissionEmployee::setSocialSecurityNumber(
48 const string &ssn )
49 {
50 socialSecurityNumber = ssn; // should validate
51 } // end function setSocialSecurityNumber
52
36
53 // return social security number
54 string BasePlusCommissionEmployee::getSocialSecurityNumber() const
55 {
56 return socialSecurityNumber;
57 } // end function getSocialSecurityNumber
58 Example 2
59 // set gross sales amount BasePlus
60 void BasePlusCommissionEmployee::setGrossSales( double sales )
Commission
61 {
Employee.cpp
62 grossSales = ( sales < 0.0 ) ? 0.0 : sales;
63 } // end function setGrossSales
(3 of 4)
64
65 // return gross sales amount
66 double BasePlusCommissionEmployee::getGrossSales() const
67 {
68 return grossSales;
69 } // end function getGrossSales
70
71 // set commission rate
72 void BasePlusCommissionEmployee::setCommissionRate( double rate )
73 {
74 commissionRate = ( rate > 0.0 && rate < 1.0 ) ? rate : 0.0;
75 } // end function setCommissionRate
76
77 // return commission rate
78 double BasePlusCommissionEmployee::getCommissionRate() const
79 {
80 return commissionRate;
81 } // end function getCommissionRate
82
37
83 // set base salary
84 void BasePlusCommissionEmployee::setBaseSalary( double salary )
85 {
86 baseSalary = ( salary < 0.0 ) ? 0.0 : salary;
87 } // end function setBaseSalary
Function setBaseSalary validates data
88 and sets instance variable baseSalary
89 // return base salary
90 double BasePlusCommissionEmployee::getBaseSalary() const
91 {
92 return baseSalary;
93 } // end function getBaseSalary Function getBaseSalary returns the
94 value of instance variable baseSalary
95 // calculate earnings
96 double BasePlusCommissionEmployee::earnings() const
97 {
98 return baseSalary + ( commissionRate * grossSales );
99 } // end function earnings
100 Update function earnings to calculate the
101 // print BasePlusCommissionEmployee object earnings of a base-salaried commission employee
102 void BasePlusCommissionEmployee::print() const
103 {
104 cout << "base-salaried commission employee: " << firstName << ' '
105 << lastName << "\nsocial security number: " << socialSecurityNumber
106 << "\ngross sales: " << grossSales
107 << "\ncommission rate: " << commissionRate
Update function print
108 << "\nbase salary: " << baseSalary;
109 } // end
to display base salary
function print
Example 2
BasePlus
Commission
Employee.cpp (3 of 4)
1 // Fig. 12.9: fig12_09.cpp
2 // Testing class BasePlusCommissionEmployee.
3 #include <iostream>
4 using std::cout;
5 using std::endl;
6 using std::fixed;
7
8 #include <iomanip> Example 2
9 using std::setprecision;
testBase.cpp (1 of 2)
10
11 // BasePlusCommissionEmployee class definition
12 #include "BasePlusCommissionEmployee.h"
13
14 int main()
15 {
16 // instantiate BasePlusCommissionEmployee object
17 BasePlusCommissionEmployee
18 employee( "Bob", "Lewis", "333-33-3333", 5000, .04, 300 );
19
20 // set floating-point output formatting
21 cout << fixed << setprecision( 2 );
22
Instantiate BasePlusCommissionEmployee object
39
23 // get commission employee data
24 cout << "Employee information obtained by get functions: \n"
25 << "\nFirst name is " << employee.getFirstName()
26 << "\nLast name is " << employee.getLastName()
Use BasePlusCommissionEmployee’s
27 << "\nSocial security number is "
get functions to retrieve the object’s instance
28 << employee.getSocialSecurityNumber()
variable values
29 << "\nGross sales is " << employee.getGrossSales()
30 << "\nCommission rate is " << employee.getCommissionRate()
31 << "\nBase salary is " << employee.getBaseSalary() << endl;
32
33 employee.setBaseSalary( 1000 ); // set base salary
34
35
Use BasePlusCommissionEmployee’s
cout << "\nUpdated employee information output by print function: \n"
36 << endl; setBaseSalary function to set base salary
37 employee.print(); // display the new employee information
38 Call object’s print function to
39 // display the employee's earnings display employee information
40 cout << "\n\nEmployee's earnings: $" << employee.earnings() << endl;
41
42 return 0;
43 } // end main
Call object’s earnings function
Example 2 to calculate employee’s earnings
testBase.cpp (1 of 2)
40
Similarities Example 1 & Example 2
l There are more similarities than differences between the code for the
CommissionEmployee class and the code for the
BasePlusCommissionEmployee class
n These two classes are classes that a sales organization would likely need both of in
their payroll system
41
Software Engineering Observation
l With inheritance, the common data members
and member functions of all the classes in the
hierarchy are declared in a base class.
n When changes are required for these common
features, software developers need to make the
changes only in the base class—derived classes then
inherit the changes.
42
Inheritance First Attempt (Example 3)
l Example 3
l For this first attempt at Inheritance we are going to leave the
CommissionEmployee class as is and attempt to rewrite
BasePlusCommissionEmployee as a derived class of Commission
Employee
n We're going to see there are a few problems with this approach and there are some changes
to CommissionEmployee we should make for the inheritance
l Class BasePlusCommissionEmployee
n Derived from class CommissionEmployee
♦ Is a CommissionEmployee
♦ Inherits all members (remember the inherited private members will not be directly accessible)
n DEFAULT BEHAVIOR OF CONSTRUCTORS/DESTRUCTORS IN INHERITANCE:
Constructor is not inherited/Destructor is not inherited as we'll see in a second
♦ Use base-class initializer syntax to initialize base-class data members
♦ NOTE: The new C++11 standard has a way to inherit constructors we'll test this out in some examples
later – but for test purposes if I ask about the default behavior constructors are NOT inherited
♦ This first example will use the default behavior of constructors/destructors NOT being inherited
by the derived class
n Has an additional data member baseSalary (specialization by extension)
♦ Also has the additional get and set functions for this member (more specialization)
n We will also want to redefine the earnings and print functions to customize (specialization by
enhancement)
43
1 // Fig. 12.10: BasePlusCommissionEmployee.h
2 // BasePlusCommissionEmployee class derived from class
3 // CommissionEmployee.
4 #ifndef BASEPLUS_H
5 #define BASEPLUS_H
6
7 #include <string> // C++ standard string class
Include the base-class header file
8 using std::string;
in the derived-class header file
9
10 #include "CommissionEmployee.h" // CommissionEmployee class declaration
11
12 class BasePlusCommissionEmployee : public CommissionEmployee
13 {
14 public:
15 BasePlusCommissionEmployee( const string &, const string &,
16 const string &, double = 0.0, double = 0.0, double = 0.0 );
17
Class BasePlusCommissionEmployee derives
18 void setBaseSalary( double ); // set base salary
publicly from class CommissionEmployee
19 double getBaseSalary() const; // return base salary
20
21 double earnings() const; // calculate earnings
22 void print() const; // print BasePlusCommissionEmployee object Example 3
23 private:
BasePlus
24 double baseSalary; // base salary Commission
25 }; // end class BasePlusCommissionEmployee Employee.h
26
27 #endif (1 of 1)
44
Comments – Example 3 Specification (.h)
l The colon (:) in line 12 is used to indicate inheritance and public
indicates the type of inheritance
n We said with public inheritance the derived class inherits all the
members of the base class
♦ This is true except for the constructor and the destructor (if there were
one) (remember we are talking about default behavior here with no new
standard stuff yet)
l This means our derived class BasePlusCommissionEmployee must
include its own constructor but inherits all other members of the base
class CommissionEmployee
n Note that we cannot see the inherited members of
CommissionEmployee just by looking at
BasePlusCommissionEmployee's source code but:
♦ they ARE inherited and thus can be used by any object of the
BasePlusCommissionEmployee class
n Note that our derived class does redefine earnings() and
print() even though they are inherited because we specialized
them to enhance/customize their functionality (we did this by
redefining them)
45
1 // Fig. 12.11: BasePlusCommissionEmployee.cpp
2 // Class BasePlusCommissionEmployee member-function definitions.
3 #include <iostream>
4 using std::cout;
5
6 // BasePlusCommissionEmployee class definition
7 #include "BasePlusCommissionEmployee.h"
8 Example 3
9 // constructor BasePlus
10 BasePlusCommissionEmployee::BasePlusCommissionEmployee( Commission
11 const string &first, const string &last, const string &ssn,
Employee.cpp
12 double sales, double rate, double salary )
13 // explicitly call base-class constructor
(1 of 2)
14 : CommissionEmployee( first, last, ssn, sales, rate )
15 {
16 setBaseSalary( salary ); // validate and store base salary
17 } // end BasePlusCommissionEmployee constructor
18
19 // set base salary
20 void BasePlusCommissionEmployee::setBaseSalary( double salary )
21 {
Initialize base class data member by calling the base-class constructor
22 baseSalary = ( salary < 0.0 ) ? 0.0 : salary; using base-class initializer syntax – REQUIRED with non-inherited
23 } // end function setBaseSalary constructor/destructor (remember constructors and destructors are by
24 DEFAULT not inherited, the new standard has some way to maybe
25 // return base salary change this but this will be the way we do it most of the time)
26 double BasePlusCommissionEmployee::getBaseSalary() const
27 {
28 return baseSalary;
29 } // end function getBaseSalary
46
Comments – Example 3 Implementation Part 1 (.cpp)
47
Including the base class header file
l Note that I included the base class's header file in the derived
class's header file (#include "CommissionEmployee.h")
l Base class header file must be included in derived class header file
for three reasons, the compiler must
1. Know that base class exists
♦ in order to use the base class's name in the constructor or elsewhere
2. Know size of inherited data members
♦ A client program that creates an instance of an object must include the class
definition to reserve the proper amount of memory for the object
♦ With inheritance, a derived class's object's size regarding this depends on the
data members declared explicitly in its class definition AND the data members
inherited from both its direct and indirect base classes
l Including the base class's definition in the derived class's header allows this to
happen (the compiler to correctly determine the memory requirements for the
base class's data members that become part of a derived-class object) and
thus
3. Ensure that inherited class members are used properly
♦ For example that private base class members aren't directly accessed
48
30
31 // calculate earnings
32 double BasePlusCommissionEmployee::earnings() const
33 {
34 // derived class cannot access the base class’s private data
35 return baseSalary + ( commissionRate * grossSales );
36 } // end function earnings
37
Compiler generates errors because base class’s data
38 // print BasePlusCommissionEmployee object
member commissionRate and grossSales
39 void BasePlusCommissionEmployee::print() const
are private inherited members
40 {
41 // derived class cannot access the base class’s private data
42 cout << "base-salaried commission employee: " << firstName << ' '
43 << lastName << "\nsocial security number: " << socialSecurityNumber
44 << "\ngross sales: " << grossSales
45 << "\ncommission rate: " << commissionRate Compiler generates errors because the base
46 << "\nbase salary: " << baseSalary; class’s data members firstName,
47 } // end function print lastName, socialSecurityNumber,
grossSales and commissionRate are
Example 3 private
BasePlus
Commission
Employee.cpp
(1 of 2)
49
Comments – Example 3 Implementation Part 2 (.cpp)
50
Performance Tip
l In a derived-class constructor, initializing
member objects and invoking base-class
constructors explicitly in the member initializer
list:
n prevents duplicate initialization in the case where a default
constructor is called, and then data members are modified
again in the derived-class constructor’s body.
51
Linking Process
l The linking process requires:
n the object code for all classes used in the program AND the
object code of the direct and indirect base classes of any derived
classes used in the program
52
Inheritance & protected data (Example 4)
l Example 4
n We can use protected data members to allow the
BasePlusCommissionEmployee derived class to directly
access the CommissionEmployee private base class data
members of:
♦ firstName, lastName, socialSecurityNumber, grossSales, and
commissionRate
53
1 // Fig. 12.12: CommissionEmployee.h
2 // CommissionEmployee class definition with protected data.
3 #ifndef COMMISSION_H
4 #define COMMISSION_H
5
6 #include <string> // C++ standard string class
7 using std::string;
Example 4
8 Commission
9 class CommissionEmployee Employee.h
10 {
11 public: (1 of 2)
12 CommissionEmployee( const string &, const string &, const string &,
13 double = 0.0, double = 0.0 );
14
15 void setFirstName( const string & ); // set first name
16 string getFirstName() const; // return first name
17
18 void setLastName( const string & ); // set last name
19 string getLastName() const; // return last name
20
21 void setSocialSecurityNumber( const string & ); // set SSN
22 string getSocialSecurityNumber() const; // return SSN
23
54
24 void setGrossSales( double ); // set gross sales amount
25 double getGrossSales() const; // return gross sales amount
26
27 void setCommissionRate( double ); // set commission rate
28 double getCommissionRate() const; // return commission rate
29
30 double earnings() const; // calculate earnings
31 void print() const; // print CommissionEmployee object
32 protected:
33 string firstName;
Declare protected data
34 string lastName;
35 string socialSecurityNumber;
36 double grossSales; // gross weekly sales
Example 4
37 double commissionRate; // commission percentage
38 }; // end class CommissionEmployee Commission
39 Employee.h
40 #endif
(2 of 2)
55
1 // Fig. 12.13: CommissionEmployee.cpp
2 // Class CommissionEmployee member-function definitions.
3 #include <iostream>
4 using std::cout;
5
6 #include "CommissionEmployee.h" // CommissionEmployee class definition
7
8 // constructor
9 CommissionEmployee::CommissionEmployee(
10 const string &first, const string &last, const string &ssn,
11 double sales, double rate )
12 {
13 firstName = first; // should validate
14
15
lastName = last; // should validate
socialSecurityNumber = ssn; // should validate
Example 4
16 setGrossSales( sales ); // validate and store gross sales Commission
17 setCommissionRate( rate ); // validate and store commission rate Employee.cpp
18 } // end CommissionEmployee constructor
19 (1 of 4)
20 // set first name
21 void CommissionEmployee::setFirstName( const string &first )
22 {
23 firstName = first; // should validate
24 } // end function setFirstName
25
26 // return first name
27 string CommissionEmployee::getFirstName() const
28 {
29 return firstName;
30 } // end function getFirstName
56
31
32 // set last name
33 void CommissionEmployee::setLastName( const string &last )
34 {
35 lastName = last; // should validate
36 } // end function setLastName
37
38 // return last name
39 string CommissionEmployee::getLastName() const
40 {
41 return lastName;
42 } // end function getLastName
43
44
45
// set social security number
void CommissionEmployee::setSocialSecurityNumber( const string &ssn )
Example 4
46 { Commission
47 socialSecurityNumber = ssn; // should validate Employee.cpp
48 } // end function setSocialSecurityNumber
49 (2 of 4)
50 // return social security number
51 string CommissionEmployee::getSocialSecurityNumber() const
52 {
53 return socialSecurityNumber;
54 } // end function getSocialSecurityNumber
55
56 // set gross sales amount
57 void CommissionEmployee::setGrossSales( double sales )
58 {
59 grossSales = ( sales < 0.0 ) ? 0.0 : sales;
60 } // end function setGrossSales
57
61
62 // return gross sales amount
63 double CommissionEmployee::getGrossSales() const
64 {
65 return grossSales;
66 } // end function getGrossSales
67
68 // set commission rate
69 void CommissionEmployee::setCommissionRate( double rate )
70 {
71 commissionRate = ( rate > 0.0 && rate < 1.0 ) ? rate : 0.0;
72 } // end function setCommissionRate
73
74 // return commission rate Example 4
75 double CommissionEmployee::getCommissionRate() const Commission
76 { Employee.cpp
77 return commissionRate;
78 } // end function getCommissionRate (3 of 4)
79
80 // calculate earnings
81 double CommissionEmployee::earnings() const
82 {
83 return commissionRate * grossSales;
84 } // end function earnings
58
85
86 // print CommissionEmployee object
87 void CommissionEmployee::print() const
88 {
89 cout << "commission employee: " << firstName << ' ' << lastName
90 << "\nsocial security number: " << socialSecurityNumber
91 << "\ngross sales: " << grossSales
92 << "\ncommission rate: " << commissionRate;
93 } // end function print
Example 4
Commission
Employee.cpp
(4 of 4)
59
1 // Fig. 12.14: BasePlusCommissionEmployee.h
2 // BasePlusCommissionEmployee class derived from class
3 // CommissionEmployee.
4 #ifndef BASEPLUS_H
5 #define BASEPLUS_H
6 Example 4
7 #include <string> // C++ standard string class BasePlus
8 using std::string; Commission
9 Employee.h
10 #include "CommissionEmployee.h" // CommissionEmployee class declaration
11 (1 of 1)
12 class BasePlusCommissionEmployee : public CommissionEmployee
13 { BasePlusCommissionEmployee
14 public: still inherits publicly from
15 BasePlusCommissionEmployee( const string &, const string &,
CommissionEmployee
16 const string &, double = 0.0, double = 0.0, double = 0.0 );
17
18 void setBaseSalary( double ); // set base salary
19 double getBaseSalary() const; // return base salary
20
21 double earnings() const; // calculate earnings
22 void print() const; // print BasePlusCommissionEmployee object
23 private:
24 double baseSalary; // base salary
25 }; // end class BasePlusCommissionEmployee
26
27 #endif
60
1 // Fig. 12.15: BasePlusCommissionEmployee.cpp
2 // Class BasePlusCommissionEmployee member-function definitions.
3 #include <iostream>
4 using std::cout;
5
6 // BasePlusCommissionEmployee class definition
7 #include "BasePlusCommissionEmployee.h"
8
9 // constructor
10 BasePlusCommissionEmployee::BasePlusCommissionEmployee( Call base-class constructor using
11 const string &first, const string &last, const string &ssn,
base-class initializer syntax
12 double sales, double rate, double salary )
13 // explicitly call base-class constructor
14 : CommissionEmployee( first, last, ssn, sales, rate )
15 {
16 setBaseSalary( salary ); // validate and store base salary
Example 4
BasePlus
17 } // end BasePlusCommissionEmployee constructor
18
Commission
19 // set base salary
Employee.cpp
20 void BasePlusCommissionEmployee::setBaseSalary( double salary )
21 { (1 of 2)
22 baseSalary = ( salary < 0.0 ) ? 0.0 : salary;
23 } // end function setBaseSalary
24
25 // return base salary
26 double BasePlusCommissionEmployee::getBaseSalary() const
27 {
28 return baseSalary;
29 } // end function getBaseSalary
61
30
31 // calculate earnings
32 double BasePlusCommissionEmployee::earnings() const
33 {
34 // can access protected data of base class
35 return baseSalary + ( commissionRate * grossSales );
36 } // end function earnings
37
38 // print BasePlusCommissionEmployee object
Directly access base
39 void BasePlusCommissionEmployee::print() const
class’s protected data
40 {
41 // can access protected data of base class
42 cout << "base-salaried commission employee: " << firstName << ' '
43 << lastName << "\nsocial security number: " << socialSecurityNumber Example 4
44 << "\ngross sales: " << grossSales
BasePlus
45 << "\ncommission rate: " << commissionRate Commission
46 << "\nbase salary: " << baseSalary; Employee.cpp
47 } // end function print
(1 of 2)
62
1 // Fig. 12.16: fig12_16.cpp
2 // Testing class BasePlusCommissionEmployee.
3 #include <iostream>
4 using std::cout;
5 using std::endl;
6 using std::fixed;
7
8 #include <iomanip>
Example 4
testInheritance2
9 using std::setprecision;
.cpp
10
11 // BasePlusCommissionEmployee class definition
12 #include "BasePlusCommissionEmployee.h"
(1 of 2)
13
14 int main()
15 {
16 // instantiate BasePlusCommissionEmployee object
17 BasePlusCommissionEmployee
18 employee( "Bob", "Lewis", "333-33-3333", 5000, .04, 300 );
19
20 // set floating-point output formatting
21 cout << fixed << setprecision( 2 );
22
Note that the output of all the test programs (with and without Inheritance)
are identical
-The advantages of the inheritance is in the code saved by having
the derived class absorb the duplicate members of the base
class
-In addition, this will make maintenance, modifying and
debugging easier and less error prone
-This also makes code more reusable
63
23 // get commission employee data
24 cout << "Employee information obtained by get functions: \n"
25 << "\nFirst name is " << employee.getFirstName()
26 << "\nLast name is " << employee.getLastName()
27 << "\nSocial security number is "
28 << employee.getSocialSecurityNumber()
29 << "\nGross sales is " << employee.getGrossSales() Example 4
30 << "\nCommission rate is " << employee.getCommissionRate() testInheritance2
31 << "\nBase salary is " << employee.getBaseSalary() << endl; .cpp
32
33 employee.setBaseSalary( 1000 ); // set base salary (2 of 2)
34
35 cout << "\nUpdated employee information output by print function: \n"
36 << endl;
37 employee.print(); // display the new employee information
38
39 // display the employee's earnings
40 cout << "\n\nEmployee's earnings: $" << employee.earnings() << endl;
41
42 return 0;
43 } // end main
64
Notes on using protected data
l Using protected data members
l Advantages
n Derived class can modify values directly
♦ Avoid set/get method call overhead
l Slight increase in performance
n In most cases though, it is better to use private data members to encourage proper
software engineering and leave code optimization issues to the compiler
l Disadvantages
n Using protected data members causes two serious problems
1. No validity checking
♦ Derived class can assign illegal values to private members since they don’t have to use set
functions to access them
2. Implementation dependent
♦ Derived class functions more likely to be written so that they are dependent on base class
implementation (base class member variables) if protected is used
l It's better to have the classes be dependent on the base-class services (non-private member
functions) than on the actual base class implementation (private members)
§ if the implementation of the inherited public functions change the derived class doesn't have to
worry about the changes (if it only uses the functions and not the members)
§ but if the inherited private members directly change and the derived class directly accesses them
the derived class will also have to change
♦ Base class implementation changes to private members may result in derived class
modifications if the derived class directly accesses them – this is not true in the case of just
using inherited public functions (think of the soda machine)
l Fragile (brittle) software
65
Software Engineering Tips
l It is appropriate to use the protected access specifier
when:
n a base class should provide a service (i.e., a member function)
only to its derived classes (and friends), not to other clients.
66
Inheritance good Software Engineering (Example 5)
l Example 5
l Reexamine hierarchy
n Use the best software engineering practice
♦ Declare data members as private
♦ Provide public get and set functions
♦ Use get methods to obtain values of data members always
whenever possible
n We will have the print() and earnings() functions call
the base class functions needed rather than directly
accessing base class implementation data
♦ This means if the base class for some reason decided to
change the data member names, the earnings() and
print() function definitions of the derived class would not
require modification
l These types of changes only change things in the
base class not the derived class
67
1 // Fig. 12.17: CommissionEmployee.h
2 // CommissionEmployee class definition with good software engineering.
3 #ifndef COMMISSION_H
4 #define COMMISSION_H
5
6
7
#include <string> // C++ standard string class
using std::string;
Example 5
8 Commission
9 class CommissionEmployee Employee.h
10 {
11 public: (1 of 2)
12 CommissionEmployee( const string &, const string &, const string &,
13 double = 0.0, double = 0.0 );
14
15 void setFirstName( const string & ); // set first name
16 string getFirstName() const; // return first name
17
18 void setLastName( const string & ); // set last name
19 string getLastName() const; // return last name
20
21 void setSocialSecurityNumber( const string & ); // set SSN
22 string getSocialSecurityNumber() const; // return SSN
23
24 void setGrossSales( double ); // set gross sales amount
25 double getGrossSales() const; // return gross sales amount
26
27 void setCommissionRate( double ); // set commission rate
28 double getCommissionRate() const; // return commission rate
68
29
30 double earnings() const; // calculate earnings
31 void print() const; // print CommissionEmployee object
32 private:
33 string firstName;
Declare private data
34 string lastName;
35 string socialSecurityNumber;
36 double grossSales; // gross weekly sales Example 5
37 double commissionRate; // commission percentage Commission
38 }; // end class CommissionEmployee Employee.h
39
40 #endif (2 of 2)
69
1 // Fig. 12.18: CommissionEmployee.cpp
2 // Class CommissionEmployee member-function definitions.
3 #include <iostream>
4 using std::cout;
5
6 #include "CommissionEmployee.h" // CommissionEmployee class definition
7
8 // constructor
Example 5
Commission
9 CommissionEmployee::CommissionEmployee(
10 const string &first, const string &last, const string &ssn,
Employee.cpp
11 double sales, double rate )
12 : firstName( first ), lastName( last ), socialSecurityNumber( ssn ) (1 of 4)
13 {
14 setGrossSales( sales ); // validate and store gross sales
Use member initializers
to set the values
15 setCommissionRate( rate ); // validate and store commission rate
16 } // end CommissionEmployee constructor
of members firstName, lastname
17 and socialSecurityNumber
18 // set first name
19 void CommissionEmployee::setFirstName( const string &first )
20 {
21 firstName = first; // should validate
22 } // end function setFirstName
23
24 // return first name
25 string CommissionEmployee::getFirstName() const
26 {
27 return firstName;
28 } // end function getFirstName
70
29
30 // set last name
31 void CommissionEmployee::setLastName( const string &last )
32 {
33 lastName = last; // should validate
34 } // end function setLastName
35
36 // return last name
Example 5
37 string CommissionEmployee::getLastName() const Commission
38 { Employee.cpp
39 return lastName;
40 } // end function getLastName (2 of 4)
41
42 // set social security number
43 void CommissionEmployee::setSocialSecurityNumber( const string &ssn )
44 {
45 socialSecurityNumber = ssn; // should validate
46 } // end function setSocialSecurityNumber
47
48 // return social security number
49 string CommissionEmployee::getSocialSecurityNumber() const
50 {
51 return socialSecurityNumber;
52 } // end function getSocialSecurityNumber
53
54 // set gross sales amount
55 void CommissionEmployee::setGrossSales( double sales )
56 {
57 grossSales = ( sales < 0.0 ) ? 0.0 : sales;
58 } // end function setGrossSales
71
59
60 // return gross sales amount
61 double CommissionEmployee::getGrossSales() const
62 {
63 return grossSales;
64 } // end function getGrossSales
65
66 // set commission rate
Example 5
67 void CommissionEmployee::setCommissionRate( double rate ) Commission
68 { Employee.cpp
69 commissionRate = ( rate > 0.0 && rate < 1.0 ) ? rate : 0.0;
70 } // end function setCommissionRate (3 of 4)
71
72 // return commission rate
73 double CommissionEmployee::getCommissionRate() const
74 {
75 return commissionRate;
76 } // end function getCommissionRate
77
78 // calculate earnings Use get functions to obtain
79 double CommissionEmployee::earnings() const the values of data members
80 {
81 return getCommissionRate() * getGrossSales();
82 } // end function earnings
83
72
84 // print CommissionEmployee object
85 void CommissionEmployee::print() const
86 {
87 cout << "commission employee: "
88 << getFirstName() << ' ' << getLastName()
89 << "\nsocial security number: " << getSocialSecurityNumber()
90 << "\ngross sales: " << getGrossSales()
91 << "\ncommission rate: " << getCommissionRate();
92 } // end function print Use get functions to obtain
the values of data members
Example 5
Commission
Employee.cpp
(4 of 4)
73
Performance Tip
l Using a member function to access a data
member’s value can be slightly slower than
accessing the data directly.
n However, today’s optimizing compilers are carefully
designed to perform many optimizations implicitly
♦ (such as inlining set and get member-function calls).
♦ As a result, programmers should write code that adheres to
proper software engineering principles, and leave
optimization issues to the compiler.
l A good rule is, “Do not second-guess the compiler.”
74
1 // Fig. 12.19: BasePlusCommissionEmployee.h
2 // BasePlusCommissionEmployee class derived from class
3 // CommissionEmployee.
4 #ifndef BASEPLUS_H
5 #define BASEPLUS_H
6
7 #include <string> // C++ standard string class
Example 5
8 using std::string; BasePlus
9 Commission
10 #include "CommissionEmployee.h" // CommissionEmployee class declaration Employee.h
11
12 class BasePlusCommissionEmployee : public CommissionEmployee (1 of 1)
13 {
14 public:
15 BasePlusCommissionEmployee( const string &, const string &,
16 const string &, double = 0.0, double = 0.0, double = 0.0 );
17
18 void setBaseSalary( double ); // set base salary
19 double getBaseSalary() const; // return base salary
20
21 double earnings() const; // calculate earnings
22 void print() const; // print BasePlusCommissionEmployee object
23 private:
24 double baseSalary; // base salary
25 }; // end class BasePlusCommissionEmployee
26
27 #endif
75
1 // Fig. 12.20: BasePlusCommissionEmployee.cpp
2 // Class BasePlusCommissionEmployee member-function definitions.
3 #include <iostream>
4 using std::cout;
5
6 // BasePlusCommissionEmployee class definition
7 #include "BasePlusCommissionEmployee.h"
8
9 // constructor
10 BasePlusCommissionEmployee::BasePlusCommissionEmployee(
Example 5
11 const string &first, const string &last, const string &ssn,
12 double sales, double rate, double salary ) BasePlus
13 // explicitly call base-class constructor Commission
14 : CommissionEmployee( first, last, ssn, sales, rate ) Employee.cpp
15 {
16 setBaseSalary( salary ); // validate and store base salary (1 of 2)
17 } // end BasePlusCommissionEmployee constructor
18
19 // set base salary
20 void BasePlusCommissionEmployee::setBaseSalary( double salary )
21 {
22 baseSalary = ( salary < 0.0 ) ? 0.0 : salary;
23 } // end function setBaseSalary
24
25 // return base salary
26 double BasePlusCommissionEmployee::getBaseSalary() const
27 {
28 return baseSalary;
29 } // end function getBaseSalary
76
30
31 // calculate earnings
32 double BasePlusCommissionEmployee::earnings() const
33 {
34 return getBaseSalary() + CommissionEmployee::earnings();
35 } // end function earnings
36
Invoke base class’s earnings function
37 // print BasePlusCommissionEmployee object
38 void BasePlusCommissionEmployee::print() const
39 {
40 cout << "base-salaried ";
41
42 // invoke CommissionEmployee's print function
43 CommissionEmployee::print();
44
45 cout << "\nbase salary: " << getBaseSalary(); Invoke base class’s print function
46 } // end function print
78
1 // Fig. 12.21: fig12_21.cpp
2 // Testing class BasePlusCommissionEmployee.
3 #include <iostream>
4 using std::cout;
5 using std::endl;
6 using std::fixed;
7
8 #include <iomanip>
9 using std::setprecision;
10
Example 5
11 // BasePlusCommissionEmployee class definition testInheritance3.cpp
12 #include "BasePlusCommissionEmployee.h"
13 (1 of 2)
79
14 int main()
15 {
16 // instantiate BasePlusCommissionEmployee object
17 BasePlusCommissionEmployee
18 employee( "Bob", "Lewis", "333-33-3333", 5000, .04, 300 );
19
20 // set floating-point output formatting
21 cout << fixed << setprecision( 2 ); Create BasePlusCommissionEmployee object
22
23 // get commission employee data
24 cout << "Employee information obtained by get functions: \n"
25 << "\nFirst name is " << employee.getFirstName()
26 << "\nLast name is " << employee.getLastName()
27 << "\nSocial security number is " Use inherited get methods to access
28 << employee.getSocialSecurityNumber() base class private members
29 << "\nGross sales is " << employee.getGrossSales()
30 << "\nCommission rate is " << employee.getCommissionRate()
31 << "\nBase salary is " << employee.getBaseSalary() << endl;
32 Use BasePlusCommissionEmployee
33 employee.setBaseSalary( 1000 ); // set base salary
get method to access private member
34
35 cout << "\nUpdated employee information output by print function: \n"
36 << endl;
Use BasePlusCommissionEmployee set method
37 employee.print(); // display the new to modify
employee private data member baseSalary
information
38
39 // display the employee's earnings Example 5
40 cout << "\n\nEmployee's earnings: $" << employee.earnings() << endl;
testInheritance3.cpp
41
42 return 0;
43 } // end main (2 of 2)
80
Examples 1-5
l They all work identically but the best
engineered example is Example 5
n You want to start trying to use good software
engineering techniques in your code
81
C++11 (New Standard) Inheriting Base Class
Constructors
l Some of these new standard things are implemented in some compilers and not
others so I'm just mentioning them as something you might want to try but something
that will be more relevant in the future
l The new standard allows use to explicitly inherit a base class constructor
n you do it with the following using declaration which can be placed anywhere in the derived class
definition (you will have to explore I'm not sure but it sound like the .h or the .cpp)
♦ using BaseClass::BaseClass; //BaseClass is the name of the base class
♦ The general result of the above using declaration is that for each constructor in the base class the
compiler generates a derived class constructor that calls the corresponding base class constructor
l These generated constructors perform only DEFAULT INITIALIZATION for any derived class specialized
member variables
83
Constructors, Destructors & Inheritance
l Instantiating derived-class objects begins a chain of constructor calls
n Derived-class constructor invokes base class constructor
♦ Implicitly (by calling the default or no-arg constructor) or explicitly (via
base class member initializer)
♦ If the base class is derived from another class it too is required to invoke the
constructor one up the inheritance change before itself and so on
♦ The very top Base class of inheritance hierarchy
l is the Last constructor called in chain
l is the First constructor body to finish executing
l Example: CommissionEmployee/BasePlusCommissionEmployee
hierarchy
§ CommissionEmployee constructor called last
§ CommissionEmployee constructor body finishes execution first
l The class at the bottom of the hierarchy is the first constructor called and the
last one to finish executing
n Initializing data members
♦ Each base-class constructor initializes its data members that are inherited by
derived class
84
Software Engineering Observation
l When a program creates a derived-class object
n the derived-class constructor immediately calls the base-
class constructor
n the base-class's member initializers execute followed by
the base class constructor’s body executing
n then the derived class’s member initializers execute
n and finally the derived-class constructor’s body executes.
85
Constructors, Destructors & Inheritance
l Destroying derived-class object
n Chain of destructor calls
♦ Reverse order of constructor chain
♦ Destructor of derived-class called first
♦ Destructor of next base class up hierarchy next
l Continue up hierarchy until final base reached
86
More Constructors, Destructors & Inheritance
l Suppose that we create an object of a derived class
where both the base class and the derived class
contain objects of other classes (composition – so
now we have inheritance and composition).
n When an object of that derived class is created, first the
constructors for the base class’s member objects execute
n then the base-class constructor executes
n then the constructors for the derived class’s member objects
execute
n then the derived class’s constructor executes.
n Destructors for derived-class objects are called in the reverse of
the order in which their corresponding constructors are called.
87
Base Access Specification
l When we created our derived classes we specified
what's called a base access specification before the
name of the class we were deriving from:
n class Student : public Person
♦ So public is the base access specification
88
public, protected and private Inheritance
l We said with inheritance the base class can be executed through
public, private, or protected inheritance
n protected and private inheritance are rare and each should only
be used if there is a very good reason
89
Base Access Specification
Base Class How members of the base class appear in the
Access Derived class
Specification
private lPrivate members of the base class are inaccessible to the derived class
90
Software Engineering with Inheritance
l Customizing existing software
n Inheriting from existing classes
♦ Can include additional members
♦ Can redefine base-class members
♦ No direct access to base class’s source code
l Only links to object code
n Independent software vendors (ISVs)
♦ Develop proprietary code for sale/license
l Available in object-code format
♦ Users derive new classes
l Without accessing ISV proprietary source code
91
Software Engineering Tips
l At the design stage in an object-oriented system,
the designer often determines that certain
classes are closely related.
n The designer should “factor out” common attributes and
behaviors and place these in a base class
♦ and then use inheritance to form derived classes, giving them
with capabilities beyond those inherited from the base class.
92