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

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

Проблем

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

Касата трябва да сумира цените на покупките. Понякога са две, понякога три. Методът е един и същ по смисъл: „сумирай“. Как да го напишеш и за двата случая, без да измисляш имена като Total2 и Total3?

Ето една подсказка: вече ползваш метод, който приема различни неща. Console.WriteLine печата и 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;
}
Console.WriteLine(Total(2.5, 4.0));
Console.WriteLine(Total(2.5, 4.0, 1.5));
Изход
6.5
8

При всяко извикване компилаторът гледа аргументите и избира метода, който пасва. Два аргумента: първият метод. Три: вторият. Затова и WriteLine работи с всичко: това са много методи с едно име.

static double Total(double a, double b)
{
return a + b;
}
static double Total(double a, double b, double c)
{
return a + b + c;
}
Console.WriteLine(Total(2.5, 4.0));
Console.WriteLine(Total(2.5, 4.0, 1.5));
Стъпка по стъпка, с думи
  1. Извикване с два аргумента: Total(2.5, 4.0).
  2. Методите са два, с едно име. Компилаторът брои аргументите: два. Пасва методът с два параметъра.
  3. Аргументите отиват в a и b. Методът връща 6.5.
  4. Сега аргументите са три.
  5. Пасва другият метод, с три параметъра. Той връща 8.
  6. Едно име, два метода. Кой да се извика, решават аргументите.

Пробвай

Кой метод?

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

static void Describe(int x)
{
Console.WriteLine("цяло: " + x);
}
static void Describe(double x)
{
Console.WriteLine("дробно: " + x);
}
Describe(5);
Describe(5.0);
Describe(7 / 2);
Отговор

Пробвай

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

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

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

Идеята

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

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

static double Total(params double[] prices)
{
double sum = 0;
foreach (double p in prices)
{
sum += p;
}
return sum;
}
Console.WriteLine(Total(1.5, 2.0, 3.5, 4.0));
Console.WriteLine(Total(9.99));
Console.WriteLine(Total());
Изход
11
9.99
0

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

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

Пробвай

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

static double Total( double[] prices)
{
    double sum = 0;
    foreach (double p in 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(params int[] grades) връща средното на произволен брой оценки, а без оценки връща 0.

Извикване
Average(5, 6, 4)
Average(6, 5)
Average()
Изход
5
5.5
0

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

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

Тест

Провери се

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

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