Към съдържанието
wannacode

Претоварване

Проблем

Две покупки, три покупки

Касата трябва да сумира цените на покупките. Понякога са две, понякога три. Методът е един и същ по смисъл: „сумирай“. Как да го напишеш и за двата случая, без да измисляш имена като 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.5
8.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));
Стъпка по стъпка, с думи
  1. Извикване с два аргумента: total(2.5, 4.0).
  2. Методите са два, с едно име. Компилаторът брои аргументите: два. Пасва методът с два параметъра.
  3. Аргументите отиват в a и b. Методът връща 6.5.
  4. Сега аргументите са три.
  5. Пасва другият метод, с три параметъра. Той връща 8.0.
  6. Едно име, два метода. Кой да се извика, решават аргументите.

Пробвай

Кой метод?

Какво ще отпечата програмата?

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);
Отговор

Пробвай

Намери грешката

Програмата не се компилира. На кой ред е проблемът?

Избери реда с грешката.

Идеята

Колкото искаш аргументи

А ако покупките са пет? Двайсет? Не пишеш метод за всеки брой. Казваш, че методът приема произволен брой аргументи от един тип:

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.0
9.99
0.0

Трите точки след типа (double... prices) значат: „подай колкото искаш числа“. Вътре в метода те пристигат като масив, който може да е и празен.

По-точно, за любопитните
  • Такъв параметър може да е само един и трябва да е последен: print(String title, double... prices).
  • Ако има и метод с точно два параметъра, и метод с произволен брой, при два аргумента се вика първият. Точното съвпадение печели.

Пробвай

Какво липсва?

static double total(double prices) {
    double sum = 0;
    for (double p : prices) {
        sum += p;
    }
    return sum;
}

Упражнение

Едно име, няколко метода

1. Най-голямото. Напиши три метода с едно име max: за две цели числа, за три цели числа (той вика първия два пъти) и за две дробни.

Извикване
max(3, 8)
max(4, 9, 2)
max(2.5, 1.5)
Изход
8
9
2.5

2. Среден успех. Метод average(int... grades) връща средното на произволен брой оценки, а без оценки връща 0.

Извикване
average(5, 6, 4)
average(6, 5)
average()
Изход
5.0
5.5
0.0

3. Ред от бележката. printLine(String item, int qty) печата „Кафе x 2“. Добави printLine(String item) за една бройка. Той не повтаря кода, а вика първия метод с 1.

Изход
Кафе x 2
Кроасан x 1

Тест

Провери се

1. Кога два метода в един клас могат да се казват еднакво?
2. Как компилаторът избира кой от претоварените методи да извика?
3. Какво е double... prices вътре в метода?
4. Кое от тези НЕ се компилира?

Създаден от Иво Гергов като част от кампанията на Evo Tech за достъпно обучение по програмиране ·