Претоварване
Проблем
Две покупки, три покупки
Касата трябва да сумира цените на покупките. Понякога са две, понякога три. Методът е един и същ по смисъл: „сумирай“. Как да го напишеш и за двата случая, без да измисляш имена като 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.58При всяко извикване компилаторът гледа аргументите и избира метода, който пасва. Два аргумента: първият метод. Три: вторият. Затова и 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));Стъпка по стъпка, с думи
- Извикване с два аргумента: Total(2.5, 4.0).
- Методите са два, с едно име. Компилаторът брои аргументите: два. Пасва методът с два параметъра.
- Аргументите отиват в a и b. Методът връща 6.5.
- Сега аргументите са три.
- Пасва другият метод, с три параметъра. Той връща 8.
- Едно име, два метода. Кой да се извика, решават аргументите.
Пробвай
Кой метод?
Какво ще отпечата програмата?
static void Describe(int x){ Console.WriteLine("цяло: " + x);}
static void Describe(double x){ Console.WriteLine("дробно: " + 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(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());119.990Думата 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;
}params double[] prices: думата params пред масива.Упражнение
Едно име, няколко метода
1. Най-голямото. Напиши три метода с едно име Max: за две цели числа, за три цели числа (той вика първия два пъти) и за две дробни.
Max(3, 8)Max(4, 9, 2)Max(2.5, 1.5)892.52. Среден успех. Метод Average(params int[] grades) връща средното на произволен брой оценки, а без оценки връща 0.
Average(5, 6, 4)Average(6, 5)Average()55.503. Ред от бележката. PrintLine(string item, int qty) печата „Кафе x 2“. Добави PrintLine(string item) за една бройка. Той не повтаря кода, а вика първия метод с 1.
Кафе x 2Кроасан x 1Тест