Method Overloading

Things To Do First

Things To Do Later

Method Overloading

Read!
Read Chapter 6.8 first!

In using some of the existing classes in Java, you might have noticed that in the documentation, some classes have multiple versions of methods with the same name. For example, JOptionPane actually has 2 or 3 different versions of methods like showMessageDialog()? Why would you define more than one method with the same name?

Examine code listing 6.9 in chapter 6.8. In this program, three different versions of the max() method have been created: one to find the max of two ints, one to find the max of two doubles, and one to find the max of three doubles. When you want to perform a task in different ways, you can create multiple methods with the same name. Each method takes the inputs it needs, and they all return the same kind of value. Notice that each max() method takes a different set of arguments, but they all return the same thing - the maximum of the values given in the inputs.

When a class or program contains two or more methods with the same name, it is called method overloading. Method overloading allows other programmers to invoke methods in different ways to suit their needs. This is part of the larger object-oriented concept known as polymorphism.

You've used method overloading already in Java. There are multiple versions of the println() method. One version takes a string value, one version takes an integer value, and one version even takes a double value. That's why all of these statements work:

String str = "hi";
int intNum = 5;
double dblNum = 5.5;
System.out.println(str);
System.out.println(intNum);
System.out.println(dblNum);

When defining overloaded methods, the method names must be the same and the parameter lists must be different. For example, the following two method headers define an overloaded method called calculatePay():

public double calculatePay(int deptNum) { ... }
public double calculatePay(double hours, double rate) { ... }

When you invoke the calculatePay() method, Java will locate the correct method to execute based on the parameter list. So if you were to call the calculatePay() with the statement:

double pay = calculatePay(8.5, 24.50);

..then Java would locate the calculatePay() method that had two double parameter variables. If you were to execute the statement:

double pay = calculatePay(2);

..then Java would locate the calculatePay() method that had one integer parameter variable (or one double, since an int can be implicitly cast into a double).

If you were to try the statement:

double pay = calculatePay("Sales Department");

Then you would receive an error that the method calculatePay(java.lang.String) didn't exist: there is no calculatePay() method that takes a String.

You have to be careful to avoid ambiguous invocation when defining overloaded methods. For example, the following overloaded methods would not be valid:

public static String findCustomer(String firstName) { ... }
public static String findCustomer(String lastName) { ... }

In the above example, Java sees two findCustomer() methods with a String parameter. The name of the parameter is irrelevant; Java sees these two method definitions as being exactly the same.

In general, you can overload methods as long as the parameter list is different. You can also change the return types, but again, only if the parameter lists are different. Therefore these methods are valid:

public static  int getValidNumber(String prompt, int min, int max) { ... }
public static double getValidNumber(String prompt, double max) { ... }

These are valid because the parameter list differs between the two. However, the methods below are not valid because even though the return types are different, the parameter lists are the same:

public static  int getValidNumber(String prompt, int min, int max) { ... }
public static double getValidNumber(String prompt, int min, int max) { ... }

Exercises

[solutions]

1. What is wrong with the following program?

public class Overloading {
    
    public static void main(String[] args) {
        doStuff("Kaluha");
        doStuff("Kaluha", 5);
    }
	
    public static void doStuff(String message) {
        System.out.println(message);
    }

    public static void doStuff(String message, int num) {
        for (int i=1; i<=num; i++)
            System.out.println(message);
    }

    public static boolean doStuff(String name) {
        return name.equalsIgnoreCase("kaluha")
    }
}

2. A program calculates and displays bonus amounts to pay various types of employees. There are 3 separate departments, numbered 1, 2, and 3. Department 1 employees are paid a bonus based on their sales: If their sales amount is over $5000 they get 5% of those sales, otherwise they get nothing. Department 2 employees are paid a bonus based on the number of units they sell: They get $20 per unit sold, and an extra $10 per unit if they sell 25 units or more; if they sell no units, they get nothing. Department 3 employees assemble parts in the plant and are paid a bonus of 10 cents per part if they reach a certain level: Part-time employees must assemble more than 250 parts to get the 10-cent-per-part bonus, and full-time employees must assemble more than 700.

Write a set of 3 overloaded methods called getBonus() that works with the program below, according to the specifications described above.

public final static int UNITS_PT = 250;
public final static int UNITS_FT = 700;
public final static double SALES_BONUS = 5000.0;
public final static double SALES_BONUS_RATE = 0.05;
public final static double SALES_UNIT_REG = 20.0;
public final static double SALES_UNIT_EXTRA = 10.0;
public final static int SALES_UNIT_BONUS = 25;
public final static double PARTS_BONUS = 0.1;

    public static void main(String[] args) {

    Scanner keysIn = new Scanner(System.in);
    System.out.println("Enter department: ");
    int dept = keysIn.nextInt();
    double bonus = 0;

    switch (dept)	{
        case 1:
            System.out.print("Enter sales: ");
            double sales = keysIn.nextDouble();
            bonus = getBonus(sales);
            break;
        case 2:
            System.out.print("Enter number of units sold: ");
            int numUnits = keysIn.nextInt();
            bonus = getBonus(numUnits);
            break;
        case 3:
            System.out.print("Enter # of pieces completed: ");
            int pieces = keysIn.nextInt();
            System.out.print("Full-time (1) or Part-Time (2)? ");
            int empType = keysIn.nextInt();
            int bonusLimit = (empType == 1) ? UNITS_FT : UNITS_PT;
            bonus = getBonus(pieces, bonusLimit);
            break;
        default:
            System.out.print("Error!  ");
	 }
	 System.out.printf("Bonus Amount: $%.2f%n", bonus);
}