Претоварване
Проблем
Две покупки, три покупки
Касата трябва да сумира цените на покупките. Понякога са две, понякога три. Методът е един и същ по смисъл: „сумирай“. Как да го напишеш и за двата случая, без да измисляш имена като total2 и total3?
Ето една подсказка: вече ползваш метод, който приема различни неща. System.out.println печата и 5, и 2.5, и текст. Как го прави?
Идеята
Едно име, различни параметри
Два метода може да се казват еднакво, ако параметрите им се различават: по брой, по тип или по ред. Това се казва претоварване (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.0При всяко извикване компилаторът гледа аргументите и избира метода, който пасва. Два аргумента: първият метод. Три: вторият. Затова и println работи с всичко: това са много методи с едно име.
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));Стъпка по стъпка, с думи
- Извикване с два аргумента: total(2.5, 4.0).
- Методите са два, с едно име. Компилаторът брои аргументите: два. Пасва методът с два параметъра.
- Аргументите отиват в a и b. Методът връща 6.5.
- Сега аргументите са три.
- Пасва другият метод, с три параметъра. Той връща 8.0.
- Едно име, два метода. Кой да се извика, решават аргументите.
Пробвай
Кой метод?
Какво ще отпечата програмата?
static void describe(int x) { System.out.println("цяло: " + x);}
static void describe(double x) { System.out.println("дробно: " + x);}
describe(5);describe(5.0);describe(7 / 2);5 е int, 5.0 е double. А 7 / 2 е деление на две цели числа: резултатът е цялото число 3, затова се вика методът за int.
Пробвай
Намери грешката
Програмата не се компилира. На кой ред е проблемът?
Избери реда с грешката.
Двата метода имат еднакви параметри (int percent) и се различават само по типа на резултата. При извикване discount(15) компилаторът няма как да избере. Второто име трябва да е друго, например discountRate.
Идеята
Колкото искаш аргументи
А ако покупките са пет? Двайсет? Не пишеш метод за всеки брой. Казваш, че методът приема произволен брой аргументи от един тип:
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.0Трите точки след типа (double... prices) значат: „подай колкото искаш числа“. Вътре в метода те пристигат като масив, който може да е и празен.
По-точно, за любопитните
- Такъв параметър може да е само един и трябва да е последен:
print(String title, double... prices). - Ако има и метод с точно два параметъра, и метод с произволен брой, при два аргумента се вика първият. Точното съвпадение печели.
Пробвай
Какво липсва?
static double total(double prices) {
double sum = 0;
for (double p : prices) {
sum += p;
}
return sum;
}double... prices: трите точки след типа.Упражнение
Едно име, няколко метода
1. Най-голямото. Напиши три метода с едно име max: за две цели числа, за три цели числа (той вика първия два пъти) и за две дробни.
max(3, 8)max(4, 9, 2)max(2.5, 1.5)892.52. Среден успех. Метод average(int... grades) връща средното на произволен брой оценки, а без оценки връща 0.
average(5, 6, 4)average(6, 5)average()5.05.50.03. Ред от бележката. printLine(String item, int qty) печата „Кафе x 2“. Добави printLine(String item) за една бройка. Той не повтаря кода, а вика първия метод с 1.
Кафе x 2Кроасан x 1Тест