Overloading
Problem
Two items, three items
The till has to add up the prices of the items. Sometimes there are two, sometimes three. The method means the same thing either way: "add up". How do you write it for both cases without making up names like total2 and total3?
Here is a hint: you already use a method that takes different things. System.out.println prints 5, 2.5 and text too. How does it do that?
The idea
One name, different parameters
Two methods can have the same name if their parameters differ: in number, in type or in order. This is called overloading.
static double total(double a, double b) { return a + b;}
static double total(double a, double b, double c) { return a + b + c;}
System.out.println(total(2.5, 4.0));System.out.println(total(2.5, 4.0, 1.5));6.58.0At each call, the compiler looks at the arguments and picks the method that fits. Two arguments: the first method. Three: the second one. That is also why println works with everything: it is many methods with one name.
static double total(double a, double b) { return a + b;}
static double total(double a, double b, double c) { return a + b + c;}
System.out.println(total(2.5, 4.0));System.out.println(total(2.5, 4.0, 1.5));Step by step, in words
- A call with two arguments: total(2.5, 4.0).
- There are two methods with one name. The compiler counts the arguments: two. The method with two parameters fits.
- The arguments go into a and b. The method returns 6.5.
- Now there are three arguments.
- The other method fits, the one with three parameters. It returns 8.0.
- One name, two methods. The arguments decide which one is called.
Try it
Which method?
What will the program print?
static void describe(int x) { System.out.println("whole: " + x);}
static void describe(double x) { System.out.println("decimal: " + x);}
describe(5);describe(5.0);describe(7 / 2);5 is an int, 5.0 is a double. And 7 / 2 divides two whole numbers: the result is the whole number 3, so the method for int is called.
Try it
Find the bug
The program does not compile. Which line is the problem on?
Pick the line with the bug.
The two methods have the same parameters (int percent) and differ only in the type of the result. In the call discount(15) the compiler has no way to choose. The second name has to be different, for example discountRate.
The idea
As many arguments as you like
What if there are five items? Twenty? You do not write a method for each count. You say that the method takes any number of arguments of one type:
static double total(double... prices) { double sum = 0; for (double p : prices) { sum += p; } return sum;}
System.out.println(total(1.5, 2.0, 3.5, 4.0));System.out.println(total(9.99));System.out.println(total());11.09.990.0The three dots after the type (double... prices) mean: "pass as many numbers as you like". Inside the method they arrive as an array, which can also be empty.
More precisely, if you are curious
- There can be only one such parameter, and it has to be the last one:
print(String title, double... prices). - If there is a method with exactly two parameters and also a method with any number, a call with two arguments goes to the first one. The exact match wins.
Try it
What is missing?
static double total(double prices) {
double sum = 0;
for (double p : prices) {
sum += p;
}
return sum;
}double... prices: the three dots after the type.Exercise
One name, several methods
1. The largest. Write three methods with one name, max: for two whole numbers, for three whole numbers (it calls the first one twice) and for two decimals.
max(3, 8)max(4, 9, 2)max(2.5, 1.5)892.52. Average grade. The method average(int... grades) returns the average of any number of grades, and with no grades it returns 0.
average(5, 6, 4)average(6, 5)average()5.05.50.03. A receipt line. printLine(String item, int qty) prints "Coffee x 2". Add printLine(String item) for a single item. It does not repeat the code: it calls the first method with 1.
Coffee x 2Croissant x 1Test