Перегрузка методов
Перегрузка — это несколько методов с одним именем, но разными параметрами. Она позволяет называть одинаково действия, которые делают одно и то же с разными данными. Вы уже пользовались перегрузкой: IO.println() принимает и строки, и числа, и boolean.
Разное число параметров
Методы с одним именем различаются количеством параметров. Java выбирает версию по числу аргументов в вызове:
int sum(int a, int b) {
return a + b;
}
int sum(int a, int b, int c) {
return a + b + c;
}
void main() {
IO.println(sum(2, 3));
IO.println(sum(2, 3, 4));
}Результат:
5
9Разные типы параметров
Версии могут отличаться и типами параметров. Тогда Java смотрит на типы аргументов:
void describe(int value) {
IO.println("Целое число: " + value);
}
void describe(double value) {
IO.println("Дробное число: " + value);
}
void describe(String value) {
IO.println("Строка: " + value);
}
void main() {
describe(10);
describe(2.5);
describe("Java");
}Результат:
Целое число: 10
Дробное число: 2.5
Строка: JavaИмя метода вместе со списком типов параметров называется сигнатурой. У перегруженных методов сигнатуры должны различаться. Имена параметров в сигнатуру не входят: describe(int value) и describe(int number) — один и тот же метод.
Как Java выбирает версию
Сначала ищется точное совпадение типов. Если его нет, Java пробует автоматическое расширение типа, например int → long → double:
void show(long value) {
IO.println("long: " + value);
}
void show(double value) {
IO.println("double: " + value);
}
void main() {
show(5);
show(5.0f);
}Результат:
long: 5
double: 5.0Метода для int нет, поэтому 5 попадает в ближайший более широкий тип — long. float расширяется до double.
Значения по умолчанию
В Java нет параметров со значением по умолчанию. Их заменяет перегрузка: короткая версия вызывает полную и подставляет недостающий аргумент:
void order(String drink, int cups) {
IO.println(drink + " x" + cups);
}
void order(String drink) {
order(drink, 1);
}
void main() {
order("Латте", 3);
order("Эспрессо");
}Результат:
Латте x3
Эспрессо x1Логика живёт в одном методе, а остальные версии только передают ему данные.
Когда перегрузка уместна
Перегружайте методы, которые делают одно и то же. Если действия разные, дайте им разные имена: findById и findByName понятнее, чем два метода find с похожими параметрами.
Частая ошибка
Методы нельзя перегрузить только типом результата — при вызове total(2, 3) Java не смогла бы выбрать версию:
int total(int a, int b) {
return a + b;
}
double total(int a, int b) {
return a + b;
}
void main() {
IO.println(total(2, 3));
}Результат:
Main.java:5: error: method total(int,int) is already defined in class Main
double total(int a, int b) {
^
1 error
error: compilation failedСписок параметров должен отличаться количеством, типами или их порядком.