Search code examples
javaarrayspolymorphismtest-data

Java Polymorphic processing: Incorrect output?


In the following class I am trying to print details of Employees in a payroll system. Note that Porter, Pharmacist and Surgeon all inherit from Employee.

However it is only repeatedly printing details of the first employee added to the array. I know the expected output but I am unable to reproduce it.

Class:

public class PayrollManager {

    public static final int HOURS_PER_WEEK = 35;

    public static Employee[] employees = new Employee[6];

    public static void main(String[] args) {

        // create all employees
        Employee generalEmployee = new Employee("Odd", "Jobbie", 10.50);
        Employee porter1 = new Porter("Ivana", "Patient", 10.50, "Royal");
        Employee porter2 = new Porter("Amanda", "Pushabed", 10.50, "BCH");
        Employee surgeon1 = new Surgeon("Jack", "Ripper", 55.25, "Renal",
                650.00);
        Employee surgeon2 = new Surgeon("Edward", "Lister", 55.25, "Vascular",
                800.00);
        Employee pharmacist = new Pharmacist("Poppy", "Pill", 30.50, 7, 750);

        // call method to handle adding the employees to the list
        addEmployeeToList(generalEmployee);
        addEmployeeToList(porter1);
        addEmployeeToList(porter2);
        addEmployeeToList(surgeon1);
        addEmployeeToList(surgeon2);
        addEmployeeToList(pharmacist);

        // show all employees
        displayAllEmployees();
        System.out.println();
        // run payroll
        processWeeklyPayroll();

    }// end of main

    /**
     * Method to add an Employee to an array
     * 
     * @param e
     */
    public static void addEmployeeToList(Employee e) {

        for (int loop = 0; loop < employees.length; loop++) {
            // check there is a space
            if (employees[loop] == null) {
                // add it to free space
                employees[loop] = e;

            }
        }

    }

    public static void displayAllEmployees() {

        for (Employee e : employees) {

            if (e != null) {

                e.displayAll();
                System.out.println();
            }
        }
    }

    public static void processWeeklyPayroll() {

        for (Employee e : employees) {

            if (e != null) {

                e.calculateWeeklySalary(HOURS_PER_WEEK);
                // line break
                System.out.println();
            }
        }

    }

}

Current Output:

[Employee] Odd Jobbie 10.500000
[Employee] Odd Jobbie 10.500000
[Employee] Odd Jobbie 10.500000
[Employee] Odd Jobbie 10.500000
[Employee] Odd Jobbie 10.500000
[Employee] Odd Jobbie 10.500000

Odd Jobbie [Base Rate Employee] : 35.000000hrs * £10.500000= £367.500000
Odd Jobbie [Base Rate Employee] : 35.000000hrs * £10.500000= £367.500000
Odd Jobbie [Base Rate Employee] : 35.000000hrs * £10.500000= £367.500000
Odd Jobbie [Base Rate Employee] : 35.000000hrs * £10.500000= £367.500000
Odd Jobbie [Base Rate Employee] : 35.000000hrs * £10.500000= £367.500000
Odd Jobbie [Base Rate Employee] : 35.000000hrs * £10.500000= £367.500000

Note that the expected output should be printing details of each member of test data, i.e. each pharmacist, surgeon etc...


Solution

  • This is the culprit:

    public static void addEmployeeToList(Employee e) {
    
        for (int loop = 0; loop < employees.length; loop++) {
            // check there is a space
            if (employees[loop] == null) {
                // add it to free space
                employees[loop] = e;
    
            }
        }
    
    }
    

    It just sets all the employees in the list to the argument with which the function is first called; when you first call it, employees is full of null elements, so the condition is always true; but the second, third etc. time you call it, all the elements are set to the generalEmployee.

    A quick fix would be:

    public static void addEmployeeToList(Employee e) {
    
        for (int loop = 0; loop < employees.length; loop++) {
            // check there is a space
            if (employees[loop] == null) {
                // add it to free space
                employees[loop] = e;
                break;
            }
        }
    
    }
    

    But I strongly suggest using an ArrayList.

    ArrayList<Employee> employees = new ArrayList<Employee>(); //here you declare a dinamically resizing list.
    employees.add(e) //this is how you add a new Employee to the list.