30 Ağustos 2010 Pazartesi

Case Study: Payroll System Using Polymorphism

We use an abstract method and polymorphism to perform payroll calculations based on the type of employee.We create an enhanced employee hierarchy to solve the following problem:
A company pays its employees on a weekly basis. The employees are of four types: Salaried employees are paid a fixed weekly salary regardless of the number of hours worked, hourly employees are paid by the hour and receive overtime pay for all hours worked in excess of 40 hours, commission employees are paid a percentage of their sales and salaried- commission employees receive a base salary plus a percentage of their sales. For the current pay period, the company has decided to reward salaried-commission employees by adding 10% to their base salaries. The company wants to implement a Java application that performs its payroll calculations polymorphically.
 We use abstract class Employee to represent the general concept of an employee. The classes that extend Employee are SalariedEmployee, CommissionEmployee and Hourly- Employee. Class BasePlusCommissionEmployee—which extends CommissionEmployee— represents the last employee type. The UML class diagram in figure shows the inheritance hierarchy for our polymorphic employee-payroll application. Note that abstract class Employee is italicized, as per the convention of the UML. 0
Employee hierarchy UML class diagram.



Abstract superclass Employee declares the “interface” to the hierarchy—that is, the set of methods that a program can invoke on all Employee objects. We use the term “interface” here in a general sense to refer to the various ways programs can communicate with objects of any Employee subclass. Be careful not to confuse the general notion of an “interface” to something with the formal notion of a Java interface. Each employee, regardless of the way his or her earnings are calculated, has a first name, a last name and a social security number, so private instance variables firstName, lastName and socialSecurityNumber appear in abstract superclass Employee.
A subclass can inherit “interface” or “implementation” from a superclass. Hierarchies designed for implementation inheritance tend to have their functionality high in the hierarchy—each new subclass inherits one or more methods that were implemented in a superclass, and the subclass uses the superclass implementations. Hierarchies designed for interface inheritance tend to have their functionality lower in the hierarchy—a superclass specifies one or more abstract methods that must be declared for each concrete class in the hierarchy, and the individual subclasses override these methods to provide subclass-specific implementations.
Creating Abstract Superclass Employee
// 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;
   } // end method setFirstName
   // return first name
   public String getFirstName()
   {
      return firstName;
   } // end method getFirstName
   // set last name
   public void setLastName( String last )
   {
      lastName = last;
   } // 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
   public String toString()
   {
      return String.format( "%s %s\nsocial security number: %s", 
         getFirstName(), getLastName(), getSocialSecurityNumber() );
   } // end method toString
   // abstract method overridden by subclasses
   public abstract double earnings(); // no implementation here
} // end abstract class Employee
Class Employee provides methods earnings and toString, in addition to the get and set methods that manipulate Employee’s instance variables. An earnings method certainly applies generically to all employees. But each earnings calculation depends on the employee’s class. So we declare earnings as abstract in superclass Employee because a default implementation does not make sense for that method—there is not enough information to determine what amount earnings should return. Each subclass overrides earnings with an appropriate implementation. To calculate an employee’s earnings, the program assigns a reference to the employee’s object to a superclass Employee variable, then invokes the earnings method on that variable. We maintain an array of Employee variables, each of which holds a reference to an Employee object (of course, there cannot be Employee objects because Employee is an abstract class—because of inheritance, however, all objects of all subclasses of Employee may nevertheless be thought of as Employee objects). The program
iterates through the array and calls method earnings for each Employee object. Java processes these method calls polymorphically. Including earnings as an abstract method in Employee forces every direct subclass of Employee to override earnings in order to become a concrete class. This enables the designer of the class hierarchy to demand that each concrete subclass provide an appropriate pay calculation.
Method toString in class Employee returns a String containing the first name, last name and social security number of the employee. As we will see, each subclass of Employee overrides method toString to create a string representation of an object of that class that contains the employee’s type (e.g., "salaried employee:") followed by the rest of the employee’s information.
The diagram in below shows each of the five classes in the hierarchy down the left side and methods earnings and toString across the top. For each class, the diagram shows the desired results of each method. [Note: We do not list superclass Employee’s get and set methods because they are not overridden in any of the subclasses—each of these methods is inherited and used “as is” by each of the subclasses.]
Polymorphic interface for the Employee hierarchy classes.

Hiç yorum yok:

Yorum Gönder