程序功能:
1. 基类:Emplyee(普通员工)(姓名、生日、身份证号)
2. 直接子类:SalariedEmployee(固定工资员工),HourlyEmployee(小时工)、CommissionEmployee(提成工资员工)
3. 间接子类:BasePlusCommissionEmployee(基本工资加提成工资员工)
4. 打印不同员工的信息
5. 为BasePlusCommissionEmployee类型的员工增加10%的基础工资
6. 如果遇到员工的生日,该员工当月的工资增加100
运行结果:
Employees processed individually:
salaried employee: John Smith 出生年月日: 1980年10月1日 social security number: 111-11-1111 weekly salary: $800.00 earned: $800.00
hourly employee: Karen Price 出生年月日: 1970年1月31日 social security number: 222-22-2222 hourly wage: $16.75; hours worked: 40.00 earned: $670.00
commission employee: Sue Jones 出生年月日: 1990年1月18日 social security number: 333-33-3333 gross sales: $10,000.00; commission rate: 0.06 earned: $600.00
base-salaried commission employee: Bob Lewis 出生年月日: 1992年5月20日 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 出生年月日: 1980年10月1日 social security number: 111-11-1111 weekly salary: $800.00 earned $800.00
hourly employee: Karen Price 出生年月日: 1970年1月31日 social security number: 222-22-2222 hourly wage: $16.75; hours worked: 40.00 earned $770.00
commission employee: Sue Jones 出生年月日: 1990年1月18日 social security number: 333-33-3333 gross sales: $10,000.00; commission rate: 0.06 earned $700.00
base-salaried commission employee: Bob Lewis 出生年月日: 1992年5月20日 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 exercises.ch10PolymorphismAndInteface.SalariedEmployee Employee 1 is a exercises.ch10PolymorphismAndInteface.HourlyEmployee Employee 2 is a exercises.ch10PolymorphismAndInteface.CommissionEmployee Employee 3 is a exercises.ch10PolymorphismAndInteface.BasePlusCommissionEmployee
|
代码:
1. 实体类
1) Date类
import java.util.Calendar;
//JHTP Exercise 8.8: Enhancing Class Date
//by pandenghuang@163.com
/**
* 8.8 (Enhancing Class Date) Modify class Date of Fig. 8.7 to perform error
* checking on the initializer values for instance variables month, day and year
* (currently it validates only the month and day). Provide a method nextDay to
* increment the day by one. Write a program that tests method nextDay in a loop
* that prints the date during each iteration to illustrate that the method
* works correctly. Test the following cases: a) incrementing into the next
* month and b) incrementing into the next year.
*
* 8.14 (Date Class) Create class Date with the following capabilities: a)
* Output the date in multiple formats, such as 1. MM/DD/YYYY 2. June 14, 1992 3. DDD
* YYYY b) Use overloaded constructors to create Date objects initialized with
* dates of the formats in part (a). In the first case the constructor should
* receive three integer values. In the second case it should receive a String
* and two integer values. In the third case it should receive two integer
* values, the first of which represents the day number in the year. [Hint: To
* convert the String representation of the month to a numeric value, compare
* Strings using the equals method. For example, if s1 and s2 are Strings, the
* method call s1.equals(s2) returns true if the Strings are identical and
* otherwise returns false.]
*
*/
/**
*
* @author Pandenghuang@163.com
* @Date Jan 7, 2019, 12:35:19 AM
*
*/
public class Date {
private int month; // 1-12
private int day; // 1-31 based on month
private int year; // any year
private static final int[] daysPerMonth = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
//constructor: confirm proper value for month and day given the year
/**
* 使用年月日构建日期,如new Date(2019,1,7)将构建2019年1月7日
* @Date Jan 7, 2019, 12:35:31 AM
* @param year
* @param month
* @param day
*/
public Date(int year, int month, int day) {
// check for year up to next year and later than 1918 //2018年12月添加
if (year < 1918 || year > Calendar.getInstance().get(Calendar.YEAR) + 100) // 获取下一年的下100年
throw new IllegalArgumentException(
"year (" + day + ") out-of-range. A year later than 1918 and up to next 100 years is expected.");
// check if month in range
if (month <= 0 || month > 12)
throw new IllegalArgumentException("month (" + month + ") must be 1-12");
// check if day in range for month
if (day <= 0 || (day > daysPerMonth[month] && !(month == 2 && day == 29)))
throw new IllegalArgumentException("day (" + day + ") out-of-range for the specified month and year");
// check for leap year if month is 2 and day is 29
// 闰年判定规则:能被400整除,或,能被4整除但不能被100整除
if (month == 2 && day == 29 && !(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)))
throw new IllegalArgumentException("day (" + day + ") out-of-range for the specified month and year");
this.month = month;
this.day = day;
this.year = year;
//System.out.printf( "日期对象创建成功:%s%n", this);
}
//无参构造函数,创建当前日期
public Date() {
this.year = Calendar.getInstance().get(Calendar.YEAR);
this.month = Calendar.getInstance().get(Calendar.MONTH) + 1;
this.day = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
}
/**
* 构造函数: MMM DD YYYY (e8.14)
* 根据月份的英文名称,日,年创建日期
* @param monthLabel
* @param day
* @param year
*/
public Date (String monthLabel, int day, int year) {
switch (monthLabel) {
case "January":
month = 1;
break;
case "Feburary":
month = 2;
break;
case "March":
month = 3;
break;
case "April":
month = 4;
break;
case "May":
month = 5;
break;
case "June":
month = 6;
break;
case "July":
month = 7;
break;
case "August":
month = 8;
break;
case "Septemeber":
month = 9;
break;
case "October":
month = 10;
break;
case "November":
month = 11;
break;
case "December":
month = 12;
break;
}
new Date (year, month, day);
}
/**
* 构造函数: DDD YYYY (e8.14)
* 根据一年中天数的序数(第n天)及年份创建日期
* @param ddd
* @param year
*/
public Date (int ddd, int year) {
int[] accumulatedDaysNonLeapYear = {0,31,59,90,120,151,181,212,243,273,304,334,365}; //平年每月累积天数
int[] accumulatedDaysLeapYear = {0,31,60,91,121,152,182,213,244,274,305,335,366}; //闰年每月累积天数
if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) { //如果是闰年,使用闰年累计天数判断
for (int i=12; i>0;i--) {
if (ddd - accumulatedDaysLeapYear[i-1]>0) {
month = i;
day = ddd - accumulatedDaysLeapYear[i-1];
break;
}
}
}
else
for (int i=12; i>0;i--) { //如果是闰年,使用闰年累计天数判断
if (ddd - accumulatedDaysNonLeapYear[i-1]>0) {
month = i;
day = ddd - accumulatedDaysNonLeapYear[i-1];
break;
}
}
new Date (year, month, day);
}
//return a String of the form year/month/day
public String toString() {
return String.format("%d年%d月%d日", year, month, day);
}
/**
* 按照MM/DD/YYYY格式化输出 (e8.14)
* @return
*/
public String toStringMDY() {
return String.format("%02d/%02d/%d", month, day,year);
}
/**
* 按照MMM DD YYYY格式化输出 (e8.14)
* @return
*/
public String toStringMMDY() {
String mmm = "";
switch (month) {
case 1:
mmm ="January";
break;
case 2:
mmm ="Feburary";
break;
case 3:
mmm ="March";
break;
case 4:
mmm ="April";
break;
case 5:
mmm ="May";
break;
case 6:
mmm ="June";
break;
case 7:
mmm ="July";
break;
case 8:
mmm ="August";
break;
case 9:
mmm ="September";
break;
case 10:
mmm ="October";
break;
case 11:
mmm ="November";
break;
case 12:
mmm ="December";
break;
}
return String.format("%s %02d %d", mmm, day,year);
}
/**
* 按照DDD YYYY格式化输出 (ddd表示一年中的第n天,e8.14)
* @return
*/
public String toStringDDDY() {
int ddd =0;
//已经过的整月份的天数为(按平年计算)
for (int i=1;i<month;i++) {
ddd += daysPerMonth[i];
}
//加上不足整月的天数
ddd += day;
//如果是闰年,且日期在2月29日之后,则天数加一
if ((year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
&& ((month ==2 && day==29) ||month >=3))
++ddd;
return String.format("%03d %d", ddd, year);
}
//增加一天,2018年12月添加
public static Date nextDay(int year, int month, int day) {
//数据校验逻辑(与构造函数相同)
// check for year up to next year and later than 1918 //2018年12月添加
if (year < 1918 || year > Calendar.getInstance().get(Calendar.YEAR) + 100) // 获取下一年的下100年
throw new IllegalArgumentException(
"year (" + day + ") out-of-range. A year later than 1918 and up to next 100 years is expected.");
// check if month in range
if (month <= 0 || month > 12)
throw new IllegalArgumentException("month (" + month + ") must be 1-12");
// check if day in range for month
if (day <= 0 || (day > daysPerMonth[month] && !(month == 2 && day == 29)))
throw new IllegalArgumentException("day (" + day + ") out-of-range for the specified month and year");
// check for leap year if month is 2 and day is 29
// 闰年判定规则:能被400整除,或,能被4整除但不能被100整除
if (month == 2 && day == 29 && !(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)))
throw new IllegalArgumentException("day (" + day + ") out-of-range for the specified month and year");
switch (month) {
//1月,3月,5月,7月,8月,10月和12月为小月,每月31天
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
if (day + 1 > 31) {
day = 1;
if (month + 1 > 12) {// 如果是12月31日,加一天后进入新的一年的第一天(元旦)
month = 1;
++year;
} else
++month;
} else
++day; // 非月末,日期直接加一
break;
//4月,6月,9月和11月为小月,每月30天
case 4:
case 6:
case 9:
case 11:
if (day + 1 > 30) {
day = 1;
month = month + 1; // 进入下一月1号
} else
++day; // 非月末,日期直接加一
break;
case 2:// 2月既不是大月,也不是小月
if (month == 2 && day == 29 && (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))) { // 闰年,2月为29天
day = 1;
month = month + 1; // 月份前进为3月份
} else if (month == 2 && day == 28 && !(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))) { // 平年,2月为28天
day = 1;
month = month + 1; // 月份前进为3月份
} else
++day; // 非月末,日期直接加一
break;
}
return new Date(year, month, day);
}
//返回当前日期的下一天,2018年12月添加
public Date nextDay() {
int year = this.year;
int month = this.month;
int day = this.day;
switch (month) {
//1月,3月,5月,7月,8月,10月和12月为小月,每月31天
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
if (day + 1 > 31) {
day = 1;
if (month + 1 > 12) {// 如果是12月31日,加一天后进入新的一年的第一天(元旦)
month = 1;
++year;
} else
++month;
} else
++day; // 非月末,日期直接加一
break;
//4月,6月,9月和11月为小月,每月30天
case 4:
case 6:
case 9:
case 11:
if (day + 1 > 30) {
day = 1;
month = month + 1; // 进入下一月1号
} else
++day; // 非月末,日期直接加一
break;
case 2:// 2月既不是大月,也不是小月
if (month == 2 && day == 29 && (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))) { // 闰年,2月为29天
day = 1;
month = month + 1; // 月份前进为3月份
} else if (month == 2 && day == 28 && !(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))) { // 平年,2月为28天
day = 1;
month = month + 1; // 月份前进为3月份
} else
++day; // 非月末,日期直接加一
break;
}
return new Date(year, month, day);
}
/**
*
* @return 月份
* @Date Jan 7, 2019, 12:59:45 AM
*/
public int getMonth() {
return this.month;
}
} // end class Date
2) Emplyee类
//JHTP Exercise 10.12: Payroll System Modification
//by pandenghuang@163.com
/**
* 10.12 (Payroll System Modification) Modify the payroll system of Figs.
* 10.4–10.9 to include private instance variable birthDate in class Employee.
* Use class Date of Fig. 8.7 to represent an employee’s birthday. Add get
* methods to class Date. Assume that payroll is processed once per month.
* Create an array of Employee variables to store references to the various
* employee objects. In a loop, calculate the payroll for each Employee
* (polymorphically), and add a $100.00 bonus to the person’s payroll amount if
* the current month is the one in which the Employee’s birthday occurs.
*
* @author Pandenghuang@163.com
*
*/
// Fig. 10.4: Employee.java
// Employee abstract superclass.
/**
*
* @author Pandenghuang@163.com
* @Date Jan 7, 2019, 12:42:40 AM
*
*/
public abstract class Employee
{
private final String firstName;
private final String lastName;
private final String socialSecurityNumber;
private final Date birthDate;
// constructor
/**
*
* @Date Jan 7, 2019, 12:29:21 AM
* @param firstName
* @param lastName
* @param socialSecurityNumber
* @param birthDate
*/
public Employee(String firstName, String lastName, Date birthDate,
String socialSecurityNumber)
{
this.firstName = firstName;
this.lastName = lastName;
this.socialSecurityNumber = socialSecurityNumber;
this.birthDate = birthDate;
}
// return first name
public String getFirstName()
{
return firstName;
}
// return last name
public String getLastName()
{
return lastName;
}
/**
*
* @Date Jan 7, 2019, 12:26:49 AM
* @return birthDate (生日)
*/
public Date getBirthDate()
{
return birthDate;
}
// return social security number
public String getSocialSecurityNumber()
{
return socialSecurityNumber;
}
// return String representation of Employee object
@Override
public String toString()
{
return String.format("%s %s%n出生年月日: %s%nsocial security number: %s",
getFirstName(), getLastName(), getBirthDate(),getSocialSecurityNumber());
}
// abstract method must be overridden by concrete subclasses
public abstract double earnings(); // no implementation here
} // end abstract class Employee
3) SalariedEmployee类
// Fig. 10.5: SalariedEmployee.java
// SalariedEmployee concrete class extends abstract class Employee.
public class SalariedEmployee extends Employee
{
private double weeklySalary;
// constructor
/**
*
* @Date Jan 7, 2019, 12:31:20 AM
* @param firstName
* @param lastName
* @param socialSecurityNumber
* @param weeklySalary
* @param birthDate
*/
public SalariedEmployee(String firstName, String lastName, Date birthDate,
String socialSecurityNumber, double weeklySalary)
{
super(firstName, lastName,birthDate, socialSecurityNumber);
if (weeklySalary < 0.0)
throw new IllegalArgumentException(
"Weekly salary must be >= 0.0");
this.weeklySalary = weeklySalary;
}
// set salary
public void setWeeklySalary(double weeklySalary)
{
if (weeklySalary < 0.0)
throw new IllegalArgumentException(
"Weekly salary must be >= 0.0");
this.weeklySalary = weeklySalary;
}
// return salary
public double getWeeklySalary()
{
return weeklySalary;
}
// calculate earnings; override abstract method earnings in Employee
@Override
public double earnings()
{
return getWeeklySalary();
}
// return String representation of SalariedEmployee object
@Override
public String toString()
{
return String.format("salaried employee: %s%n%s: $%,.2f",
super.toString(), "weekly salary", getWeeklySalary());
}
} // end class SalariedEmployee
4) HourlyEmployee类
// Fig. 10.6: HourlyEmployee.java
// HourlyEmployee class extends Employee.
public class HourlyEmployee extends Employee
{
private double wage; // wage per hour
private double hours; // hours worked for week
// constructor
/**
*
* @Date Jan 7, 2019, 12:31:40 AM
* @param firstName
* @param lastName
* @param socialSecurityNumber
* @param wage
* @param hours
* @param birthDate
*/
public HourlyEmployee(String firstName, String lastName,Date birthDate,
String socialSecurityNumber, double wage, double hours)
{
super(firstName, lastName,birthDate, socialSecurityNumber);
if (wage < 0.0) // validate wage
throw new IllegalArgumentException(
"Hourly wage must be >= 0.0");
if ((hours < 0.0) || (hours > 168.0)) // validate hours
throw new IllegalArgumentException(
"Hours worked must be >= 0.0 and <= 168.0");
this.wage = wage;
this.hours = hours;
}
// set wage
public void setWage(double wage)
{
if (wage < 0.0) // validate wage
throw new IllegalArgumentException(
"Hourly wage must be >= 0.0");
this.wage = wage;
}
// return wage
public double getWage()
{
return wage;
}
// set hours worked
public void setHours(double hours)
{
if ((hours < 0.0) || (hours > 168.0)) // validate hours
throw new IllegalArgumentException(
"Hours worked must be >= 0.0 and <= 168.0");
this.hours = hours;
}
// return hours worked
public double getHours()
{
return hours;
}
// 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;
}
// return String representation of HourlyEmployee object
@Override
public String toString()
{
return String.format("hourly employee: %s%n%s: $%,.2f; %s: %,.2f",
super.toString(), "hourly wage", getWage(),
"hours worked", getHours());
}
} // end class HourlyEmployee
5) CommissionEmployee类
// Fig. 10.7: CommissionEmployee.java
// CommissionEmployee class extends Employee.
public class CommissionEmployee extends Employee
{
private double grossSales; // gross weekly sales
private double commissionRate; // commission percentage
// constructor
/**
*
* @Date Jan 7, 2019, 12:31:03 AM
* @param firstName
* @param lastName
* @param socialSecurityNumber
* @param birthDate
* @param grossSales
* @param commissionRate
*/
public CommissionEmployee(String firstName, String lastName, Date birthDate,
String socialSecurityNumber, double grossSales,
double commissionRate)
{
super(firstName, lastName, birthDate,socialSecurityNumber);
if (commissionRate <= 0.0 || commissionRate >= 1.0) // validate
throw new IllegalArgumentException(
"Commission rate must be > 0.0 and < 1.0");
if (grossSales < 0.0) // validate
throw new IllegalArgumentException("Gross sales must be >= 0.0");
this.grossSales = grossSales;
this.commissionRate = commissionRate;
}
// set gross sales amount
public void setGrossSales(double grossSales)
{
if (grossSales < 0.0) // validate
throw new IllegalArgumentException("Gross sales must be >= 0.0");
this.grossSales = grossSales;
}
// return gross sales amount
public double getGrossSales()
{
return grossSales;
}
// set commission rate
public void setCommissionRate(double commissionRate)
{
if (commissionRate <= 0.0 || commissionRate >= 1.0) // validate
throw new IllegalArgumentException(
"Commission rate must be > 0.0 and < 1.0");
this.commissionRate = commissionRate;
}
// return commission rate
public double getCommissionRate()
{
return commissionRate;
}
// calculate earnings; override abstract method earnings in Employee
@Override
public double earnings()
{
return getCommissionRate() * getGrossSales();
}
// return String representation of CommissionEmployee object
@Override
public String toString()
{
return String.format("%s: %s%n%s: $%,.2f; %s: %.2f",
"commission employee", super.toString(),
"gross sales", getGrossSales(),
"commission rate", getCommissionRate());
}
} // end class CommissionEmployee
6) BasePlusCommissionEmployee类
// Fig. 10.8: BasePlusCommissionEmployee.java
// BasePlusCommissionEmployee class extends CommissionEmployee.
public class BasePlusCommissionEmployee extends CommissionEmployee
{
private double baseSalary; // base salary per week
// constructor
public BasePlusCommissionEmployee(String firstName, String lastName, Date birthDate,
String socialSecurityNumber, double grossSales,
double commissionRate, double baseSalary)
{
super(firstName, lastName, birthDate,socialSecurityNumber,
grossSales, commissionRate);
if (baseSalary < 0.0) // validate baseSalary
throw new IllegalArgumentException("Base salary must be >= 0.0");
this.baseSalary = baseSalary;
}
// set base salary
public void setBaseSalary(double baseSalary)
{
if (baseSalary < 0.0) // validate baseSalary
throw new IllegalArgumentException("Base salary must be >= 0.0");
this.baseSalary = baseSalary;
}
// return base salary
public double getBaseSalary()
{
return baseSalary;
}
// calculate earnings; override method earnings in CommissionEmployee
@Override
public double earnings()
{
return getBaseSalary() + super.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 class BasePlusCommissionEmployee
2. 测试类
// Fig. 10.9: PayrollSystemTest.java
// Employee hierarchy test program.
//JHTP Exercise 10.12: Payroll System Modification
//by pandenghuang@163.com
import java.util.Calendar;
/**
* 10.12 (Payroll System Modification) Modify the payroll system of Figs.
* 10.4–10.9 to include private instance variable birthDate in class Employee.
* Use class Date of Fig. 8.7 to represent an employee’s birthday. Add get
* methods to class Date. Assume that payroll is processed once per month.
* Create an array of Employee variables to store references to the various
* employee objects. In a loop, calculate the payroll for each Employee
* (polymorphically), and add a $100.00 bonus to the person’s payroll amount if
* the current month is the one in which the Employee’s birthday occurs.
* @author Pandenghuang@163.com
* @Date Jan 7, 2019, 12:40:32 AM
*
*/
public class PayrollSystemTest
{
public static void main(String[] args)
{
// create subclass objects
SalariedEmployee salariedEmployee =
new SalariedEmployee("John", "Smith", new Date(1980,10,1),"111-11-1111", 800.00);
HourlyEmployee hourlyEmployee =
new HourlyEmployee("Karen", "Price", new Date(1970,1,31),"222-22-2222", 16.75, 40);
CommissionEmployee commissionEmployee =
new CommissionEmployee(
"Sue", "Jones", new Date(1990,1,18),"333-33-3333", 10000, .06);
BasePlusCommissionEmployee basePlusCommissionEmployee =
new BasePlusCommissionEmployee(
"Bob", "Lewis", new Date(1992,5,20),"444-44-4444", 5000, .04, 300);
System.out.println("Employees processed individually:");
System.out.printf("%n%s%n%s: $%,.2f%n%n",
salariedEmployee, "earned", salariedEmployee.earnings());
System.out.printf("%s%n%s: $%,.2f%n%n",
hourlyEmployee, "earned", hourlyEmployee.earnings());
System.out.printf("%s%n%s: $%,.2f%n%n",
commissionEmployee, "earned", commissionEmployee.earnings());
System.out.printf("%s%n%s: $%,.2f%n%n",
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.printf("Employees processed polymorphically:%n%n");
// 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%n",
employee.getBaseSalary());
}
// 如果遇到员工生日在当月,工资总额加100 (2019/01/07)
if (currentEmployee.getBirthDate().getMonth() == Calendar.getInstance().get(Calendar.MONTH)+1)
System.out.printf(
"earned $%,.2f%n%n", currentEmployee.earnings()+100);
else
System.out.printf(
"earned $%,.2f%n%n", currentEmployee.earnings());
}
// 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%n", j,
employees[j].getClass().getName());
} // end main
} // end class PayrollSystemTest