Java Arena
Step 5 of 5

Methods with the same name

You've called one method name with all kinds of values since module 1: System.out.println("Hi"), System.out.println(42), System.out.println(3.5) and System.out.println(). That isn't one method that takes anything: println is several methods with the same name, one for each type of parameter. Like constructors, methods can be overloaded, and the methods of your own classes can be too:

Main.java
public class Main {
    public static void main(String[] args) {
        LabelPrinter printer = new LabelPrinter();
        printer.print("Flour");
        printer.print(42);
        printer.print("Sugar", 2);
        System.out.println("Labels printed: " + printer.getPrinted());
    }
}
LabelPrinter.java
public class LabelPrinter {
    private int printed;

    public LabelPrinter() {
        this.printed = 0;
    }

    public void print(String text) {
        System.out.println("[ " + text + " ]");
        this.printed = this.printed + 1;
    }

    public void print(int number) {
        this.print("No. " + number);
    }

    public void print(String text, int copies) {
        for (int i = 0; i < copies; i++) {
            this.print(text);
        }
    }

    public int getPrinted() {
        return this.printed;
    }
}
Output
[ Flour ]
[ No. 42 ]
[ Sugar ]
[ Sugar ]
Labels printed: 4
  • Three methods are called print. Java picks one by the values in the call: a String runs print(String text), an int runs print(int number), and a String and an int run print(String text, int copies).
  • The other two call print(String text) instead of printing on their own, so how a label looks, and the counting, are written once. It's the same idea as this(...) in the last step, as an ordinary method call.
  • Overloading suits methods that do the same thing with different kinds of values. Methods that do different things should get different names.

Which one Java picks

Java compares the values in the call with each method's parameters: how many there are, and their types, in order. What decides is the type of each value, not what it looks like when printed. Static methods can be overloaded too, so here's the idea in Main alone:

public class Main {
    public static void main(String[] args) {
        show(5);
        show(5.0);
        show("5");
        show(2 + 3);
        show(5 / 2.0);
    }

    public static void show(int value) {
        System.out.println("int: " + value);
    }

    public static void show(double value) {
        System.out.println("double: " + value);
    }

    public static void show(String value) {
        System.out.println("String: " + value);
    }
}
Output
int: 5
double: 5.0
String: 5
int: 5
double: 2.5
  • 5.0 is a double and "5" is a String, so each goes to its own method.
  • 2 + 3 is an int, and 5 / 2.0 a double, so the type of the result decides.
  • An int also fits a double parameter, just as double distance = 5; works (module 3). Without show(int value), show(5) would run show(double value) and print double: 5.0. With both there, Java takes the one that fits exactly.

The return type doesn't count

Methods, like constructors, differ only by their parameter types. Parameter names don't count, and neither does the return type. Say you want a method that returns a label's text instead of printing it, and you call it print too:

Main.java
public class Main {
    public static void main(String[] args) {
        LabelPrinter printer = new LabelPrinter();
        printer.print("Salt");
    }
}
LabelPrinter.java
public class LabelPrinter {
    public void print(String text) {
        System.out.println("[ " + text + " ]");
    }

    public String print(String label) {
        return "[ " + label + " ]";
    }
}
What javac prints
LabelPrinter.java:6: error: method print(String) is already defined in class LabelPrinter
    public String print(String label) {
                  ^
1 error

A call such as printer.print("Salt"); doesn't have to use the value a method returns, so nothing in it could tell the two apart. A method that does something different gets a name of its own, such as labelFor(String text).

Your task

Challenge 1 of 3

An Odometer counts the kilometers a car has driven, and add(int km) adds a trip. Add a second method, add(int hours, int speed), for a trip of hours hours at speed kilometers an hour. It adds hours * speed kilometers by calling add(int km). The check runs:

Odometer odometer = new Odometer();
odometer.add(35);
odometer.add(2, 80);
System.out.println(odometer);

and expects:

195 km

Challenge 2

What does this program print? The kitchen scale has three add methods, and two of them call another one.

Challenge 3

An Alarm is set with set(int hours, int minutes). Add a second set method, set(String time), that takes the time as text, like "6:45": split it at the :, turn both parts into numbers, and call set(int hours, int minutes) with them. The check runs:

Alarm alarm = new Alarm();
alarm.set(7, 30);
System.out.println(alarm);
alarm.set("6:05");
System.out.println(alarm);

and expects:

Alarm at 7:30
Alarm at 6:05