Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Class Development 1. Employee and ProductionWorker ClassesDesign a class named E

ID: 672171 • Letter: C

Question

Class Development

1. Employee and ProductionWorker ClassesDesign a class named Employee.

The class should keep the following information in

Employee name

Employee number

Hire date (A class called 'date')

Write one or more constructors and the appropriate accessor and mutator functions for the class. Next, write a class named ProductionWorker that is derived from the Employee class. The ProductionWorker class should have member variables to hold the following information:

Shift (an integer)

Hourly pay rate (a double)

The workday is divided into two shifts: day and night. The shift variable will hold an integer value representing the shift that the employee works. The day shift is shift 1, and the night shift is shift 2. Make the shift an enumerated type. Write one or more constructors and the appropriate accessor and mutator functions for the class.

There should be a Pay function all employees - pure virtual. For Productio worker, they should be paid their hourly rate plus 1/2 additional if they work the night shift.


2. ShiftSupervisor Class

ShiftSupervisor Class In a particular factory a shift supervisor is a salaried employee who supervises a shift. In addition to a salary, the shift supervisor earns a yearly bonus when his or her shift meets production goals. Design a ShiftSupervisor class that is derived from the Employeeclass you created in Programming Challenge 1. The ShiftSupervisorclass should have a member variable that holds the annual salary and a member variable that holds the annual production bonus that a shift supervisor has earned. Write one or more constructors and the appropriate accessor and mutator functions for the class.

The Pay function for Shift Supervisor should show their normal pay and any bonus pay they earn. They are not paid hourly or do they get a shift bonus.


3. TeamLeader Class

TeamLeader Class In a particular factory, a team leader is an hourly paid production worker who leads a small team. In addition to hourly pay, team leaders earn a fixed monthly bonus. Team leaders are required to attend a minimum number of hours of training per year. Design a TeamLeader class that extends the ProductionWorker class you designed in Programming Challenge 1. The TeamLeader class should have member variables for the monthly bonus amount, the required number of training hours, and the number of training hours that the team leader has attended. Write one or more constructors and the appropriate accessor and mutator functions for the class.

The Pay function for TeamLeader should show their hourly pay and any montly bonus pay they earn based on education they have received.

Main Function

Create a main program that uses the four classes described in #1 - #3 above. The main function should have the following menu:

Create and Pay a Production Worker

Create and Pay a Shift Supervisor

Crate and Pay a Team Leader

Exit the Program

Make sure that each of these uses the specifics of each employee class/child-class. For example:

Team Leader gets additional pay (monthly) if they have had education hours to a certain point for the pay period. You should ask the user for the total hours of education they earned for that pay period and then show the total pay they receive and what is hourly and what is the education bonus

Production Worker gets paid more on the hight shift (2), so ask how many hours they worked on the day shift, then on the night shift, then show their pay broken out along with total pay

Shift Supervisor gets a bonus if their team meet their production goals. When prompting the user, ask the question if their team meets their production goals, then show their normal salary pay for the period, and any additional bonus pay they get for that pay period, along with the total pay.

Assume that the pay periods are monthly.

UML Diagram

Create a complete UML diagram for all classes (including date and utilities) used in this project. Make sure you show inheritance, agregation, and for any static classes, at least show the class with its member methods

Explanation / Answer

Payroll System Using Polymorphism

We use abstract class Employee to represent the general concept of an employee. The classes that extend Employee are SalariedEmployee, CommissionEmployee and HourlyEmployee. Class BasePlusCommissionEmployee—which extends CommissionEmployee—represents the last employee type. The UML class diagram in Fig. 10.2 shows the inheritance hierarchy for our polymorphic employee-payroll application. Abstract class name Employee is italicized—a convention of the UML.

Fig. 10.2 Employee hierarchy UML class diagram.

Fig. 10.3 Polymorphic interface for the Employee hierarchy classes.

Let's consider class Employee's declaration (Fig. 10.4). The class includes a constructor that takes the first name, last name and social security number as arguments get methods that return the first name, last name and social security number (set methods that set the first name, last name and social security number method toString), which returns the String representation of an Employee; and abstract method earnings which will be implemented by each of the concrete subclasses. The Employee constructor does not validate its parameters in this example; normally, such validation should be provided.

Fig 10.4. Employee abstract superclass.

  // Fig. 10.4: Employee.java

    // Employee abstract superclass.

    public abstract class Employee

    {

      private String firstName;

       private String lastName;

       private String socialSecurityNumber;

      // three-argument constructor

      public Employee( String first, String last, String ssn )

      {

         firstName = first;

         lastName = last;

        socialSecurityNumber = ssn;

      } // end three-argument Employee constructor

      // set first name

      public void setFirstName( String first )

      {

         firstName = first; // should validate

      } // end method setFirstName

      // return first name

     public String getFirstName()

      {

         return firstName;

      } // end method getFirstName

      // set last name

      public void setLastName( String last )

      {

         lastName = last; // should validate

      } // end method setLastName

      // return last name

      public String getLastName()

      {

         return lastName;

      } // end method getLastName

      // set social security number

      public void setSocialSecurityNumber( String ssn )

      {

         socialSecurityNumber = ssn; // should validate

      } // end method setSocialSecurityNumber

      // return social security number

      public String getSocialSecurityNumber()

      {

         return socialSecurityNumber;

      } // end method getSocialSecurityNumber

      // return String representation of Employee object

      @Override

      public String toString()

      {

         return String.format( "%s %s social security number: %s",

            getFirstName(), getLastName(), getSocialSecurityNumber() );

      } // end method toString

      // abstract method overridden by concrete subclasses       

      public abstract double earnings(); // no implementation here

   } // end abstract class Employee

Why did we decide to declare earnings as an abstract method? It simply does not make sense to provide an implementation of this method in class Employee. We cannot calculate the earnings for a general Employee—we first must know the specific type of Employee to determine the appropriate earnings calculation. By declaring this method abstract, we indicate that each concrete subclass must provide an appropriate earnings implementation and that a program will be able to use superclass Employee variables to invoke method earnings polymorphically for any type of Employee.

Class SalariedEmployee) extends class Employee and overrides abstract method earnings which makes SalariedEmployee a concrete class. The class includes a constructor that takes a first name, a last name, a social security number and a weekly salary as arguments; a set method to assign a new nonnegative value to instance variable weeklySalary a get method to return weeklySalary's value; a method earnings to calculate a SalariedEmployee's earnings; and a method toString ,which returns a String including the employee's type, namely, "salaried employee: " followed by employee-specific information produced by superclass Employee's toString method and SalariedEmployee's getWeeklySalary method. Class SalariedEmployee's constructor passes the first name, last name and social security number to the Employee constructor to initialize the private instance variables not inherited from the superclass. Method earnings overrides Employee's abstract method earnings to provide a concrete implementation that returns the SalariedEmployee's weekly salary. If we do not implement earnings, class SalariedEmployee must be declared abstract—otherwise, class SalariedEmployee will not compile. Of course, we want SalariedEmployee to be a concrete class in this example.

. SalariedEmployee concrete class extends abstract class Employee.

//: SalariedEmployee.java

   // SalariedEmployee concrete class extends abstract class Employee.

    public class SalariedEmployee extends Employee

    {

       private double weeklySalary;

       // four-argument constructor

       public SalariedEmployee( String first, String last, String ssn,

         double salary )

     {

         super( first, last, ssn ); // pass to Employee constructor

         setWeeklySalary( salary ); // validate and store salary

      } // end four-argument SalariedEmployee constructor

      // set salary

      public void setWeeklySalary( double salary )

      {

         if ( salary >= 0.0 )

            baseSalary = salary;

         else

            throw new IllegalArgumentException(

               "Weekly salary must be >= 0.0" );

      } // end method setWeeklySalary

      // return salary

      public double getWeeklySalary()

      {

         return weeklySalary;

      } // end method getWeeklySalary

      // calculate earnings; override abstract method earnings in Employee

      @Override                                                           

      public double earnings()                                           

      {

           return getWeeklySalary();                                       

      } // end method earnings                                            

      // return String representation of SalariedEmployee object  

      @Override                                                   

      public String toString()                                    

{

      return String.format( "salaried employee: %s %s: $%,.2f",

      super.toString(), "weekly salary" , getWeeklySalary() );

      } // end method toString                                    

   } // end class SalariedEmployee

Method toString (lines 40–45) overrides Employee method toString. If class SalariedEmployee did not override toString, SalariedEmployee would have inherited the Employee version of toString. In that case, SalariedEmployee's toString method would simply return the employee's full name and social security number, which does not adequately represent a SalariedEmployee. To produce a complete String representation of a SalariedEmployee, the subclass's toString method returns "salaried employee: " followed by the superclass Employee-specific information (i.e., first name, last name and social security number) obtained by invoking the superclass's toString method (line 44)—this is a nice example of code reuse. The String representation of a SalariedEmployee also contains the employee's weekly salary obtained by invoking the class's getWeeklySalary method.

Class HourlyEmployee also extends Employee The class includes a constructor that takes as arguments a first name, a last name, a social security number, an hourly wage and the number of hours worked. set methods that assign new values to instance variables wage and hours, respectively. Method setWage ensures that wage is nonnegative, and method setHours ensures that hours is between 0 and 168 (the total number of hours in a week) inclusive. Class HourlyEmployee also includes get methods to return the values of wage and hours, respectively; a method earnings to calculate an HourlyEmployee's earnings; and a method toString which returns a String containing the employee's type ("hourly employee: ") and the employee-specific information. The HourlyEmployee constructor, like the SalariedEmployee constructor, passes the first name, last name and social security number to the superclass Employee constructor to initialize the private instance variables. In addition, method toString calls superclass method toString to obtain the Employee-specific information (i.e., first name, last name and social security number)—this is another nice example of code reuse.

. HourlyEmployee class extends Employee.

   //: HourlyEmployee.java

   // HourlyEmployee class extends Employee.

   public class HourlyEmployee extends Employee

    {

       private double wage; // wage per hour

       private double hours; // hours worked for week

       // five-argument constructor

      public HourlyEmployee( String first, String last, String ssn,

         double hourlyWage, double hoursWorked )

      {

         super( first, last, ssn );

         setWage( hourlyWage ); // validate hourly wage

         setHours( hoursWorked ); // validate hours worked

      } // end five-argument HourlyEmployee constructor

      // set wage

      public void setWage( double hourlyWage )

     {

         if ( hourlyWage >= 0.0 )

            wage = hourlyWage;

         else

            throw new IllegalArgumentException(

               "Hourly wage must be >= 0.0" );

      } // end method setWage

      // return wage

      public double getWage()

      {

         return wage;

      } // end method getWage

      // set hours worked

      public void setHours( double hoursWorked )

      {

         if ( ( hoursWorked >= 0.0 ) && ( hoursWorked <= 168.0 ) )

            hours = hoursWorked;

         else

            throw new IllegalArgumentException(

               "Hours worked must be >= 0.0 and <= 168.0" );

      } // end method setHours

      // return hours worked

      public double getHours()

      {

         return hours;

      } // end method getHours

      // calculate earnings; override abstract method earnings in Employee

      @Override                                                          

      public double earnings()                                           

      {                                                                 

      if ( getHours() <= 40 ) // no overtime

      return getWage() * getHours();                               

      else                                                             

      return 40 * getWage() + ( getHours() - 40 ) * getWage() * 1.5 ;

      } // end method earnings                                           

      // return String representation of HourlyEmployee object             

      @Override                                                            

      public String toString()                                             

      {                                                                     

      return String.format( "hourly employee: %s %s: $%,.2f; %s: %,.2f",

      super.toString(), "hourly wage" , getWage(),

        "hours worked", getHours() );

      } // end method toString                                              

   } // end class HourlyEmployee

Concrete Subclass CommissionEmployee

Class CommissionEmployee extends class Employee. The class includes a constructor that takes a first name, a last name, a social security number, a sales amount and a commission rate; set methods to assign new values to instance variables commissionRate and grossSales, respectively; get methods that retrieve the values of these instance variables; method earnings to calculate a CommissionEmployee's earnings; and method toString which returns the employee's type, namely, "commission employee: " and employee-specific information. The constructor also passes the first name, last name and social security number to Employee's constructor to initialize Employee's private instance variables. Method toString calls superclass method toString to obtain the Employee-specific information (i.e., first name, last name and social security number).

. CommissionEmployee class extends Employee.

    //: CommissionEmployee.java

    // CommissionEmployee class extends Employee.

    public class CommissionEmployee extends Employee

    {

       private double grossSales; // gross weekly sales

       private double commissionRate; // commission percentage

       // five-argument constructor

      public CommissionEmployee( String first, String last, String ssn,

         double sales, double rate )

      {

         super( first, last, ssn );

         setGrossSales( sales );

         setCommissionRate( rate );

      } // end five-argument CommissionEmployee constructor

      // set commission rate

      public void setCommissionRate( double rate )

      {

         if ( rate > 0.0 && rate < 1.0 )

            commissionRate = rate;

         else

            throw new IllegalArgumentException(

              "Commission rate must be > 0.0 and < 1.0" );

      } // end method setCommissionRate

      // return commission rate

      public double getCommissionRate()

      {

         return commissionRate;

      } // end method getCommissionRate

      // set gross sales amount

      public void setGrossSales( double sales )

      {

         if ( sales >= 0.0 )

            grossSales = sales;

         else

            throw new IllegalArgumentException(

               "Gross sales must be >= 0.0" );

      } // end method setGrossSales

      // return gross sales amount

      public double getGrossSales()

      {

         return grossSales;

      } // end method getGrossSales

      // calculate earnings; override abstract method earnings in Employee

      @Override                                                          

      public double earnings()                                            

      {                                                                  

      return getCommissionRate() * getGrossSales();                   

      } // end method earnings                                           

      // return String representation of CommissionEmployee object

      @Override                                                  

      public String toString()                                   

      {                                   

      return String.format( "%s: %s %s: $%,.2f; %s: %.2f",

            "commission employee", super.toString(),             

            "gross sales", getGrossSales(),                      

            "commission rate", getCommissionRate() );             

      } // end method toString                                   

   } // end class CommissionEmployee

Indirect Concrete Subclass BasePlusCommissionEmployee

Class BasePlusCommissionEmployee) extends class CommissionEmployee (line 4) and therefore is an indirect subclass of class Employee. Class BasePlusCommissionEmployee has a constructor that takes as arguments a first name, a last name, a social security number, a sales amount, a commission rate and a base salary. It then passes all of these except the base salary to the CommissionEmployee constructor to initialize the inherited members. BasePlusCommissionEmployee also contains a set method to assign a new value to instance variable baseSalary and a get method to return baseSalary's value. Method earnings calculates a BasePlusCommissionEmployee's earnings. Line 36 in method earnings calls superclass CommissionEmployee's earnings method to calculate the commission-based portion of the employee's earnings—this is another nice example of code reuse. BasePlusCommissionEmployee's toString method creates a String representation of a BasePlusCommissionEmployee that contains "base-salaried", followed by the String obtained by invoking superclass CommissionEmployee's toString method (another example of code reuse), then the base salary. The result is a String beginning with "base-salaried commission employee" followed by the rest of the BasePlusCommissionEmployee's information. Recall that CommissionEmployee's toString obtains the employee's first name, last name and social security number by invoking the toString method of its superclass (i.e., Employee)—yet another example of code reuse. BasePlusCommissionEmployee's toString initiates a chain of method calls that span all three levels of the Employee hierarchy.

BasePlusCommissionEmployee class extends CommissionEmployee.

    //: BasePlusCommissionEmployee.java

    // BasePlusCommissionEmployee class extends CommissionEmployee.

    public class BasePlusCommissionEmployee extends CommissionEmployee

    {

       private double baseSalary; // base salary per week

       // six-argument constructor

       public BasePlusCommissionEmployee( String first, String last,

         String ssn, double sales, double rate, double salary )

      {

         super( first, last, ssn, sales, rate );

         setBaseSalary( salary ); // validate and store base salary

      } // end six-argument BasePlusCommissionEmployee constructor

      // set base salary

      public void setBaseSalary( double salary )

      {

         if ( salary >= 0.0 )

            baseSalary = salary;

         else

          throw new IllegalArgumentException(

               "Base salary must be >= 0.0" );

      } // end method setBaseSalary

      // return base salary

      public double getBaseSalary()

      {

         return baseSalary;

      } // end method getBaseSalary

      // calculate earnings; override method earnings in CommissionEmployee

      @Override                                                           

      public double earnings()                                             

      {                                                                   

      return getBaseSalary() + super.earnings();                       

      }// end method earnings                                             

      // return String representation of BasePlusCommissionEmployee object

      @Override                                                          

      public String toString()                                           

      {                                                                   

      return String.format( "%s %s; %s: $%,.2f",

            "base-salaried", super.toString(),                           

            "base salary", getBaseSalary() );                            

      } // end method toString                                           

   } // end class BasePlusCommissionEmployee

Polymorphic Processing, Operator instanceof and Downcasting

To test our Employee hierarchy, the application in creates an object of each of the four concrete classes SalariedEmployee, HourlyEmployee, CommissionEmployee and BasePlusCommissionEmployee. The program manipulates these objects nonpolymorphically, via variables of each object's own type, then polymorphically, using an array of Employee variables. While processing the objects polymorphically, the program increases the base salary of each BasePlusCommissionEmployee by 10%—this requires determining the object's type at execution time. Finally, the program polymorphically determines and outputs the type of each object in the Employee array. create objects of each of the four concrete Employee subclasses. output the String representation and earnings of each of these objects nonpolymorphically. Each object's toString method is called implicitly by printf when the object is output as a String with the %s format specifier.

. Employee hierarchy test program.

    // Fig. 10.9: PayrollSystemTest.java

   // Employee hierarchy test program.

    public class PayrollSystemTest

    {

       public static void main( String[] args )

       {

          // create subclass objects                                         

          SalariedEmployee salariedEmployee =                                

         new SalariedEmployee( "John", "Smith" , "111-11-1111", 800.00 );

         HourlyEmployee hourlyEmployee =                                     

         new HourlyEmployee( "Karen", "Price" , "222-22-2222", 16.75, 40 );

         CommissionEmployee commissionEmployee =                            

         new CommissionEmployee(                                          

         "Sue", "Jones", "333-33-3333", 10000, .06 );

         BasePlusCommissionEmployee basePlusCommissionEmployee =            

         new BasePlusCommissionEmployee(                                 

            "Bob", "Lewis", "444-44-4444", 5000, .04, 300 );                

         System.out.println( "Employees processed individually: " );

         System.out.printf( "%s %s: $%,.2f ",

            salariedEmployee, "earned", salariedEmployee.earnings() );

         System.out.printf( "%s %s: $%,.2f ",

            hourlyEmployee, "earned", hourlyEmployee.earnings() );

         System.out.printf( "%s %s: $%,.2f ",

            commissionEmployee, "earned", commissionEmployee.earnings() );

         System.out.printf( "%s %s: $%,.2f ",

            basePlusCommissionEmployee,

            "earned", basePlusCommissionEmployee.earnings() );

         // create four-element Employee array

         Employee[] employees = new Employee[ 4 ];

         // initialize array with Employees

         employees[ 0 ] = salariedEmployee;         

         employees[ 1 ] = hourlyEmployee;           

         employees[ 2 ] = commissionEmployee;       

         employees[ 3 ] = basePlusCommissionEmployee;

         System.out.println( "Employees processed polymorphically: " );

         // generically process each element in array employees

         for ( Employee currentEmployee : employees )

         {

            System.out.println( currentEmployee ); // invokes toString

            // determine whether element is a BasePlusCommissionEmployee

            if ( currentEmployee instanceof BasePlusCommissionEmployee )

            {

               // downcast Employee reference to

               // BasePlusCommissionEmployee reference

               BasePlusCommissionEmployee employee =

                  ( BasePlusCommissionEmployee ) currentEmployee;

               employee.setBaseSalary( 1.10 * employee.getBaseSalary() );

               System.out.printf(

                  "new base salary with 10%% increase is: $%,.2f ",

                  employee.getBaseSalary() );

            } // end if

            System.out.printf(

               "earned $%,.2f ", currentEmployee.earnings() );

         } // end for

         // get type name of each object in employees array

         for ( int j = 0; j < employees.length; j++ )     

            System.out.printf( "Employee %d is a %s ", j,

               employees[ j ].getClass().getName() );     

      } // end main

   } // end class PayrollSystemTest

employees processed individually:

salaried employee: John Smith

social security number: 111-11-1111

weekly salary: $800.00

earned: $800.00

hourly employee: Karen Price

social security number: 222-22-2222

hourly wage: $16.75; hours worked: 40.00

earned: $670.00

commission employee: Sue Jones

social security number: 333-33-3333

gross sales: $10,000.00; commission rate: 0.06

earned: $600.00

base-salaried commission employee: Bob Lewis

social security number: 444-44-4444

gross sales: $5,000.00; commission rate: 0.04; base salary: $300.00

earned: $500.00

Employees processed polymorphically:

salaried employee: John Smith

social security number: 111-11-1111

weekly salary: $800.00

earned $800.00

hourly employee: Karen Price

social security number: 222-22-2222

hourly wage: $16.75; hours worked: 40.00

earned $670.00

commission employee: Sue Jones

social security number: 333-33-3333

gross sales: $10,000.00; commission rate: 0.06

earned $600.00

base-salaried commission employee: Bob Lewis

social security number: 444-44-4444

gross sales: $5,000.00; commission rate: 0.04; base salary: $300.00

new base salary with 10% increase is: $330.00

earned $530.00                              

Employee 0 is a SalariedEmployee

Employee 1 is a HourlyEmployee

Employee 2 is a CommissionEmployee

Employee 3 is a BasePlusCommissionEmployee

Creating the Array of Employees

declares employees and assigns it an array of four Employee variables. assigns the reference to a SalariedEmployee object to employeesassigns the reference to an HourlyEmployee object to assigns the reference to a CommissionEmployee object to employee assigns the reference to a Base-PlusCommissionEmployee object to employeeThese assignments are allowed, because a SalariedEmployee is an Employee, an HourlyEmployee is an Employee, a CommissionEmployee is an Employee and a BasePlusCommissionEmployee is an Employee. Therefore, we can assign the references of SalariedEmployee, HourlyEmployee, CommissionEmployee and BasePlusCommissionEmployee objects to superclass Employee variables, even though Employee is an abstract class.

Polymorphically Processing Employees

iterate through array employees and invoke methods toString and earnings with Employee variable currentEmployee, which is assigned the reference to a different Employee in the array on each iteration. The output illustrates that the appropriate methods for each class are indeed invoked. All calls to method toString and earnings are resolved at execution time, based on the type of the object to which currentEmployee refers. This process is known as dynamic binding or late binding. For example, line 46 implicitly invokes method toString of the object to which currentEmployee refers. As a result of dynamic binding, Java decides which class's toString method to call at execution time rather than at compile time. Only the methods of class Employee can be called via an Employee variable (and Employee, of course, includes the methods of class Object). A superclass reference can be used to invoke only methods of the superclass—the subclass method implementations are invoked polymorphically.

Performing Type-Specific Operations on BasePlusCommissionEmployees

We perform special processing on BasePlusCommissionEmployee objects—as we encounter these objects at execution time, we increase their base salary by 10%. When processing objects polymorphically, we typically do not need to worry about the "specifics," but to adjust the base salary, we do have to determine the specific type of Employee object at execution time. Line 49 uses the instanceof operator to determine whether a particular Employee object's type is BasePlusCommissionEmployee. The condition in line 49 is true if the object referenced by currentEmployee is a BasePlusCommissionEmployee. This would also be true for any object of a BasePlusCommissionEmployee subclass because of the is-a relationship a subclass has with its superclass. Lines 53–54 downcast currentEmployee from type Employee to type BasePlusCommissionEmployee—this cast is allowed only if the object has an is-a relationship with BasePlusCommissionEmployee. The condition at line 49 ensures that this is the case. This cast is required if we're to invoke subclass BasePlusCommissionEmployee methods getBaseSalary and setBaseSalary on the current Employee object—as you'll see momentarily, attempting to invoke a subclass-only method directly on a superclass reference is a compilation error.