5.4 Method Overloading

We have already seen that the parameters of a method need not have the same types as the corresponding arguments; if the parameters are assignment compatible with the arguments, that is perfectly acceptable. Sometimes, however, it is desirable to have a method that will accept a much broader variety of arguments: possibly of very different types, possibly of various numbers. We have seen this already in the use of the predefined method System.out.println that performs correctly whatever type of argument we give it. This is an example of method overloading.

One of the most common forms of method overloading is seen in methods that have a different number of parameters. As an example, suppose that we want to use a method called rollDie that prints the result of rolling a die (the singular of dice). We might have a variety of methods to perform this task, depending on the number of times we want to roll the die and its shape.

Example 1

Methods to simulate the rolling of a die could take a number of overloaded forms.
  • One method might simply simulate the roll of one standard cubic die with six faces.
    public static void rollDie ()
    {
       System.out.println((int) (6*Math.random()+1));
    }
    We could call this method by writing
          rollDie();
    to print the result of rolling an ordinary die.


  • Another form of the method might be used to simulate repeated rolls of a standard die. It could have the header
    public static void rollDie (int rolls)
    where rolls is the number of rolls that should be simulated and printed. We could call this form of the method by writing
          rollDie(3);
    to print three rolls of an ordinary die.


  • A third form of the method might have the header
    public static void rollDie (int rolls, int faces)
    where rolls is the same as it was previously and faces is the number of faces on the die. We could call this form of the method by writing
          rollDie(2,12);
    to print two rolls of a dodecahedral (twelve-sided) die.

When a call is made to a method, the Java compiler does not simply try to find a method with an identifier that matches the identifier in the call. Instead, it performs a process called signature matching. We say that a method signature is determined by the method's identifier, the number of parameters, and the type(s) of the parameter(s) specified in the method's header.

In making a call, the compiler first tries to make an exact signature match. If it cannot do so, even though the number of arguments matches the number of parameters, it tries to see if it can make a widening conversion of the type of any of the arguments so that the resulting type matches the type of the corresponding parameter. If the method is overloaded, the version with the correct number of parameters that requires the minimal amount of widening is considered to be the best match and this is the one that will be called. If no match can be produced in this way, the call is invalid.

Example 2

Suppose that a class contains method definitions with the following headers:
   public static void doThat (int m, int n)
and
   public static void doThat (double x, int m)
  1. The call doThat(2,3); would invoke the first method.
  2. The call doThat(2.0,3); would invoke the second method.
  3. The call doThat(2,3.0); would cause an error since no signature match can be made with either version of doThat.
  4. The call doThat(3L,4); would invoke the second method; although there is no exact match for either version, widening 3L to the double value 3.0 produces a match for the second one.

Sometimes multiple matches can occur, in which case the match is ambiguous and an error will occur during compilation.

Example 3

Suppose that a class contains method definitions with the following headers:
   public static void doOther (int n, double x)
and
   public static void doOther (double x, int n) 
In this situation, the call doOther(2,3); would be ambiguous since both versions of doOther require one conversion from an int to a double. The call would produce an error.


Exercise 5.4

  1. Find an example of method overloading in Java's Math class.


  2. Suppose that two method definitions have these headers:
    1. public static void foo (int m, long n) 
    2. public static void foo (int i, int j) 
    For each of the following calls, state, with reasons, whether or not the call is valid and, if it is valid, which version of foo would be called.
    a. foo(8,4);b. foo(2L,3L);
    c. foo('A',5);d. foo(4,0.5);
    e. foo(7,6L);f. foo('x','y');

  3. Complete the definitions of the methods whose headers are given in Example 1. If rolls is less than one or faces is less than four, the methods should produce an error message.


  4. Write methods called average, each having two arguments, that will return the average of those values. If the arguments are both integers, the value returned should be an int. If either or both values are floating point numbers, the value returned should be a double. As examples,
          average(10,15) should return 12
          average(10.0,5.0) should return 7.5