11.3.2. Creating a BasePlusCommissionEmployee Class Without Using Inheritance

We now discuss the second part of our introduction to inheritance by creating and testing (a completely new and independent) class BasePlusCommissionEmployee (Figs. 11.711.8), which contains a first name, last name, social security number, gross sales amount, commission rate and base salary.


 1   // Fig. 11.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   #include <string> // C++ standard string class
 8
 9   class BasePlusCommissionEmployee
10   {
11   public:
12      BasePlusCommissionEmployee( const std::string &, const std::string &,
13         const std::string &, double = 0.0, double = 0.0, double = 0.0 );
14
15      void setFirstName( const std::string & ); // set first name
16      std::string getFirstName() const; // return first name
17
18      void setLastName( const std::string & ); // set last name
19      std::string getLastName() const; // return last name
20
21      void setSocialSecurityNumber( const std::string & ); // set SSN
22      std::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
29
30      void setBaseSalary( double ); // set base salary   
31      double getBaseSalary() const; // return base salary
32
33      double earnings() const; // calculate earnings
34      void print() const; // print BasePlusCommissionEmployee object
35   private:
36      std::string firstName;
37      std::string lastName;
38      std::string socialSecurityNumber;
39      double grossSales; // gross weekly sales
40      double commissionRate; // commission percentage
41      double baseSalary; // base salary
42   }; // end class BasePlusCommissionEmployee
43
44   #endif


Fig. 11.7. BasePlusCommissionEmployee class header.


 1   // Fig. 11.8: BasePlusCommissionEmployee.cpp
 2   // Class BasePlusCommissionEmployee member-function definitions.
 3   #include <iostream>
 4   #include <stdexcept>
 5   #include "BasePlusCommissionEmployee.h"
 6   using namespace std;
 7
 8   // constructor
 9   BasePlusCommissionEmployee::BasePlusCommissionEmployee(
10      const string &first, const string &last, const string &ssn,
11      double sales, double rate, double salary )
12   {
13      firstName = first; // should validate
14      lastName = last; // should validate
15      socialSecurityNumber = ssn; // should validate
16      setGrossSales( sales ); // validate and store gross sales
17      setCommissionRate( rate ); // validate and store commission rate
18      setBaseSalary( salary ); // validate and store base salary
19   } // end BasePlusCommissionEmployee constructor
20
21   // set first name
22   void BasePlusCommissionEmployee::setFirstName( const string &first )
23   {
24      firstName = first; // should validate
25   } // end function setFirstName
26
27   // return first name
28   string BasePlusCommissionEmployee::getFirstName() const
29   {
30      return firstName;
31   } // end function getFirstName
32
33   // set last name
34   void BasePlusCommissionEmployee::setLastName( const string &last )
35   {
36      lastName = last; // should validate
37   } // end function setLastName
38
39   // return last name
40   string BasePlusCommissionEmployee::getLastName() const
41   {
42      return lastName;
43   } // end function getLastName
44
45   // set social security number
46   void BasePlusCommissionEmployee::setSocialSecurityNumber(
47      const string &ssn )
48   {
49      socialSecurityNumber = ssn; // should validate
50   } // end function setSocialSecurityNumber
51
52   // return social security number
53   string BasePlusCommissionEmployee::getSocialSecurityNumber() const
54   {
55      return socialSecurityNumber;
56   } // end function getSocialSecurityNumber
57
58   // set gross sales amount
59   void BasePlusCommissionEmployee::setGrossSales( double sales )
60   {
61      if ( sales >= 0.0 )
62         grossSales = sales;
63      else
64         throw invalid_argument( "Gross sales must be >= 0.0" );
65   } // end function setGrossSales
66
67   // return gross sales amount
68   double BasePlusCommissionEmployee::getGrossSales() const
69   {
70      return grossSales;
71   } // end function getGrossSales
72
73   // set commission rate
74   void BasePlusCommissionEmployee::setCommissionRate( double rate )
75   {
76      if ( rate > 0.0 && rate < 1.0 )
77         commissionRate = rate;
78      else
79         throw invalid_argument( "Commission rate must be > 0.0 and < 1.0" );
80   } // end function setCommissionRate
81
82   // return commission rate
83   double BasePlusCommissionEmployee::getCommissionRate() const
84   {
85      return commissionRate;
86   } // end function getCommissionRate
87
88   // set base salary                                             
89   void BasePlusCommissionEmployee::setBaseSalary( double salary )
90   {                                                              
91      if ( salary >= 0.0 )                                        
92         baseSalary = salary;                                     
93      else                                                        
94         throw invalid_argument( "Salary must be >= 0.0" );       
95   } // end function setBaseSalary                                
96
97   // return base salary                                   
98   double BasePlusCommissionEmployee::getBaseSalary() const
99   {                                                       
100     return baseSalary;                                   
101  } // end function getBaseSalary                         
102
103  // calculate earnings                                  
104  double BasePlusCommissionEmployee::earnings() const    
105  {                                                      
106     return baseSalary + ( commissionRate * grossSales );
107  } // end function earnings                             
108
109  // print BasePlusCommissionEmployee object
110  void BasePlusCommissionEmployee::print() const
111  {
112     cout << "base-salaried commission employee: " << firstName << ' '
113        << lastName << " social security number: " << socialSecurityNumber
114        << " gross sales: " << grossSales
115        << " commission rate: " << commissionRate
116        << " base salary: " << baseSalary;
117  } // end function print


Fig. 11.8. BasePlusCommissionEmployee class represents an employee who receives a base salary in addition to a commission.

Defining Class BasePlusCommissionEmployee

The BasePlusCommissionEmployee header (Fig. 11.7) specifies class BasePlusCommissionEmployee’s public services, which include the BasePlusCommissionEmployee constructor (lines 12–13) and member functions earnings (line 33) and print (line 34). Lines 15–31 declare public get and set functions for the class’s private data members (declared in lines 36–41) firstName, lastName, socialSecurityNumber, grossSales, commissionRate and baseSalary. These variables and member functions encapsulate all the necessary features of a base-salaried commission employee. Note the similarity between this class and class CommissionEmployee (Figs. 11.411.5)—in this example, we do not yet exploit that similarity.

Class BasePlusCommissionEmployee’s earnings member function (defined in lines 104–107 of Fig. 11.8) computes the earnings of a base-salaried commission employee. Line 106 returns the result of adding the employee’s base salary to the product of the commission rate and the employee’s gross sales.

Testing Class BasePlusCommissionEmployee

Figure 11.9 tests class BasePlusCommissionEmployee. Lines 11–12 instantiate object employee of class BasePlusCommissionEmployee, passing "Bob", "Lewis", "333-33-3333", 5000, .04 and 300 to the constructor as the first name, last name, social security number, gross sales, commission rate and base salary, respectively. Lines 19–25 use BasePlusCommissionEmployee’s get functions to retrieve the values of the object’s data members for output. Line 27 invokes the object’s setBaseSalary member function to change the base salary. Member function setBaseSalary (Fig. 11.8, lines 89–95) ensures that data member baseSalary is not assigned a negative value, because an employee’s base salary cannot be negative. Line 31 of Fig. 11.9 invokes the object’s print member function to output the updated BasePlusCommissionEmployee’s information, and line 34 calls member function earnings to display the BasePlusCommissionEmployee’s earnings.


 1   // Fig. 11.9: fig11_09.cpp
 2   // BasePlusCommissionEmployee class test program.
 3   #include <iostream>
 4   #include <iomanip>
 5   #include "BasePlusCommissionEmployee.h"
 6   using namespace std;
 7
 8   int main()
 9   {
10      // instantiate BasePlusCommissionEmployee object
11      BasePlusCommissionEmployee
12         employee( "Bob", "Lewis", "333-33-3333", 5000, .04, 300 );
13
14      // set floating-point output formatting
15      cout << fixed << setprecision( 2 );
16
17      // get commission employee data
18      cout << "Employee information obtained by get functions: "
19         << " First name is " << employee.getFirstName()
20         << " Last name is " << employee.getLastName()
21         << " Social security number is "
22         << employee.getSocialSecurityNumber()
23         << " Gross sales is " << employee.getGrossSales()
24         << " Commission rate is " << employee.getCommissionRate()
25         << " Base salary is " << employee.getBaseSalary() << endl;
26
27      employee.setBaseSalary( 1000 ); // set base salary
28
29      cout << " Updated employee information output by print function: "
30         << endl;
31      employee.print(); // display the new employee information
32
33      // display the employee's earnings
34      cout << " Employee's earnings: $" << employee.earnings() << endl;
35   } // end main


Employee information obtained by get functions:

First name is Bob
Last name is Lewis
Social security number is 333-33-3333
Gross sales is 5000.00
Commission rate is 0.04
Base salary is 300.00

Updated employee information output by print function:

base-salaried commission employee: Bob Lewis
social security number: 333-33-3333
gross sales: 5000.00
commission rate: 0.04
base salary: 1000.00

Employee's earnings: $1200.00


Fig. 11.9. BasePlusCommissionEmployee class test program.

Exploring the Similarities Between Class BasePlusCommissionEmployee and Class CommissionEmployee

Most of the code for class BasePlusCommissionEmployee (Figs. 11.711.8) is similar, if not identical, to the code for class CommissionEmployee (Figs. 11.411.5). For example, in class BasePlusCommissionEmployee, private data members firstName and lastName and member functions setFirstName, getFirstName, setLastName and getLastName are identical to those of class CommissionEmployee. Classes CommissionEmployee and BasePlusCommissionEmployee also both contain private data members socialSecurityNumber, commissionRate and grossSales, as well as get and set functions to manipulate these members. In addition, the BasePlusCommissionEmployee constructor is almost identical to that of class CommissionEmployee, except that BasePlusCommissionEmployee’s constructor also sets the baseSalary. The other additions to class BasePlusCommissionEmployee are private data member baseSalary and member functions setBaseSalary and getBaseSalary. Class BasePlusCommissionEmployee’s print member function is nearly identical to that of class CommissionEmployee, except that BasePlusCommissionEmployee’s print also outputs the value of data member baseSalary.

We literally copied code from class CommissionEmployee and pasted it into class BasePlusCommissionEmployee, then modified class BasePlusCommissionEmployee to include a base salary and member functions that manipulate the base salary. This copy-and-paste approach is error prone and time consuming.


Image Software Engineering Observation 11.1

Copying and pasting code from one class to another can spread many physical copies of the same code and can spread errors throughout a system, creating a code-maintenance nightmare. To avoid duplicating code (and possibly errors), use inheritance, rather than the “copy-and-paste” approach, in situations where you want one class to “absorb” the data members and member functions of another class.



Image Software Engineering Observation 11.2

With inheritance, the common data members and member functions of all the classes in the hierarchy are declared in a base class. When changes are required for these common features, you need to make the changes only in the base class—derived classes then inherit the changes. Without inheritance, changes would need to be made to all the source code files that contain a copy of the code in question.


..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.174.95