Page 561 - Introduction to Programming with Java: A Problem Solving Approach
P. 561
13.7 Polymorphism with Arrays 527 are paid. For simplicity, this program assumes 30 days per month. If you want to learn how to get the actual
3 number of days in each month, go to Sun’s Java API Web site and read up on the Calendar class. The
day variable represents the day of the week. It determines when hourly employees are paid. Assuming that day 1 is a Monday, since the initial value of day is 2, the program’s month starts on a Tuesday. Notice how the third compartment of the for loop header executes more than one operation. It increments both date and day and then uses day%=7 to make the day variable roll over to 0 whenever it reaches 7.
The inner for loop steps through the heterogeneous array of employees. The for loop header’s second component employs a compound continuation condition. The i<employees.length condition alone would allow looping through all 100 elements of the employees array. What’s the point of the for loop header’semployees[i] != nullcondition?Theprograminstantiatesonlythreeobjectsforthisarray, and 97 elements still contain the default value of null. If the program tries to call a method with a null reference, it crashes. More specifically, it generates a NullPointerException error the first time it triestousethenullreference.Theemployees[i] != nullconditionavoidsthatbystoppingthe loop when it gets to the first null element.
Inside the inner for loop, the first if statement accumulates hours for hourly workers. It checks to see if day is a week day (not 0 or 6). It also checks to see if the object referenced by the current array element is an instance of the Hourly class. This enables the program to accumulate hours only during working days of the week and only for hourly workers. Once we know that the actual object is an instance of the Hourly class, it’s safe to cast the generic reference into an Hourly reference. So we proceed to cast that reference into type Hourly, assign it to an Hourly reference variable, then use that specific type of reference vari- able to call the addHours method. Why did we jump through those hoops? Suppose we tried to call the addHours method with our generic reference in a statement like this:
Apago PDF Enhancer
employees[i].addHours(8);
The compiler would generate the error message:
cannot find symbol
symbol : method addHours(int)
Because there is no addHours method in the Employee class, but there is one in the Hourly class, we must cast the array element explicitly into an Hourly type of reference and use that reference to call the method we need.
Now look at the second if statement in the inner for loop. Instead of accumulating hours, its purpose is generating output for a payroll report. This if statement executes if either of two or’d conditions is true. The first condition is true if it’s Friday (day 5) and if the calling object is an instance of the Hourly class. The second condition is true if it’s the middle of the month and if the calling object is not an instance of the Hourly class. If either of these conditions is satisfied, the raw array element calls the method, like this:
employees[i].printPay(date);
This strategy wouldn’t have worked with the addHours method in the first if statement, but it does work with the printPay method in the second if statement. Why? Look at the UML specification of the Employee class in Figure 13.8. This time, the method being called, printPay, is supposed to be defined in the array’s class.
3 Here’s an example of how the last day in the current month can be found:
int lastDayInCurrentMonth =
Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_MONTH);