Конструктори и this
Проблем
Кафе за 0 €
Създаваш продукт, както в миналия урок, и попълваш полетата ред по ред. Един ред си забравил:
Product coffee = new Product();coffee.Name = "Кафе";coffee.Quantity = 2;Console.WriteLine(coffee.Name + ": " + coffee.Price * coffee.Quantity + " €");Кафе: 0 €Кафето струва 0 €. Компилаторът не се оплаква: от негова гледна точка цената си има стойност, 0. Колкото повече полета има класът, толкова по-лесно е да пропуснеш едно. А продукт без цена не трябва изобщо да може да съществува.
Идеята
Конструктор: без тези данни няма обект
Класът може да каже какво е нужно, за да се създаде обект от него. За това служи конструкторът: специален метод, който се изпълнява при new.
class Product{ public string Name; public double Price; public int Quantity;
public Product(string name, double price, int quantity) { Name = name; Price = price; Quantity = quantity; }}
class Program{ static void Main() { Product coffee = new Product("Кафе", 7.50, 2); Console.WriteLine(coffee.Name + ": " + coffee.Price * coffee.Quantity + " €"); }}Кафе: 15 €- Конструкторът се казва точно като класа:
Product. - Няма тип на резултата, дори
void. - Параметрите му са данните, без които продукт няма. Те се подават в скобите на
new:new Product("Кафе", 7.50, 2).
Сега няма как да забравиш цената. Ако подадеш два аргумента вместо три, програмата не се компилира.
public Product(string name, double price, int quantity){ Name = name; Price = price; Quantity = quantity;}
Product coffee = new Product("Кафе", 7.50, 2);Console.WriteLine(coffee.Name + ": " + coffee.Price * coffee.Quantity + " €");Стъпка по стъпка, с думи
- new заделя нов обект. Полетата му са със стойности по подразбиране.
- Изпълнява се конструкторът. Аргументите се копират в параметрите му.
- Name = name: от параметъра в полето на обекта.
- Същото за цената и бройката.
- Конструкторът свърши и параметрите изчезват. В coffee отива стрелка към готовия обект.
- Обектът излиза от new вече попълнен, затова цената не е 0.
Идеята
this: полето на този обект
В C# полето е Name, а параметърът е name. Имената се различават по главната буква, затова Name = name; е ясно: отляво е полето, отдясно е параметърът.
Същото може да се напише и с this: обектът, който се създава в момента. this.Name е „полето Name на този обект“:
public Product(string name, double price, int quantity){ this.Name = name; this.Price = price; this.Quantity = quantity;}Тук this не е задължително. Ще ти трябва, когато полето и параметърът се казват еднакво. Такива полета (с малка буква) ще видиш в урока „Капсулация“: там this.balance = balance; е единственият начин да стигнеш до полето.
Пробвай
Намери грешката
Избери реда с грешката.
Name = Name; записва полето в самото него и то остава null. Трябва Name = name;, с параметъра отдясно. Компилаторът само предупреждава (CS1717: „Assignment made to same variable“), затова гледай предупрежденията.
Идеята
А new Product() от миналия урок?
В миналия урок нямаше конструктор, а new Product() работеше. Ако не напишеш конструктор, компилаторът добавя празен, без параметри. Той се казва конструктор по подразбиране и оставя полетата със стойностите им по подразбиране.
Щом напишеш свой конструктор, празният изчезва:
Product empty = new Product();error CS7036: There is no argument given that corresponds to the required parameter 'name' of 'Product.Product(string, double, int)'Това е целта: продукт без име и цена вече не може да се създаде. Ако празен конструктор все пак ти трябва, напиши го сам.
Идеята
Няколко конструктора
Повечето продукти в количката са по един брой. Да пишеш 1 всеки път е досадно.
Можеш да дадеш на класа втори конструктор, без бройката. Той стои до първия:
public Product(string name, double price){ Name = name; Price = price; Quantity = 1;}Това е претоварването от модул „Методи“: едно име, различни параметри. При new компилаторът избира конструктора по аргументите.
По-точно, за любопитните
Двата конструктора повтарят едни и същи редове. Вместо това по-краткият може да извика по-дългия:
public Product(string name, double price) : this(name, price, 1){}: this(...) след скобите вика друг конструктор на същия клас, преди да се изпълни тялото. Тук тялото е празно.
Така, ако утре добавиш проверка на цената, я пишеш само в един конструктор.
Пробвай
Кой конструктор?
Какво ще отпечата програмата?
class Product{ public string Name; public double Price; public int Quantity;
public Product(string name, double price) { Name = name; Price = price; Quantity = 1; }
public Product(string name, double price, int quantity) { Name = name; Price = price; Quantity = quantity; }}
Product bread = new Product("Хляб", 1.20);Product milk = new Product("Мляко", 2.10, 3);Console.WriteLine(bread.Quantity + " " + milk.Quantity);new Product("Хляб", 1.20) има два аргумента, затова се вика конструкторът с два параметъра. Той записва бройка 1. За млякото са подадени три аргумента и се вика другият конструктор.Пробвай
Как се казва конструкторът?
Какво трябва да пише на празното място?
class Book
{
public string Title;
public string Author;
public (string title, string author)
{
Title = title;
Author = author;
}
}Book: конструкторът се казва точно като класа, със същата главна буква.Упражнение
Обекти, създадени цели
Реши задачите в редактора си. Всеки клас получава конструктор с параметри за всички полета.
1. Човек. Клас Person с име и възраст. Създай двама души и отпечатай данните им.
Мария, 34 г.Петър, 19 г.2. Животно. Клас Animal с вид и възраст. Създай котка на 3 и куче на 7 години.
Вид: котка, възраст: 3Вид: куче, възраст: 73. Танцова стъпка. Клас DanceMove с име и продължителност в секунди. В урока „Поведение“ стъпката ще се научи да се „изпълнява“.
moonwalk: 5 сек.Още задачи
- Книга с конструктор. Препиши
Bookот миналия урок с конструкторBook(title, author). Колко реда спести в Main? -
Продукт с два конструктора.
Productс два конструктора, както в урока. Направи масив{ new Product("Хляб", 1.20, 2), new Product("Кафе", 7.50) }и отпечатай името и бройката на всеки: „Хляб x2“, „Кафе x1“. После накарай по-краткия конструктор да вика по-дългия. - Резервация. Клас
Bookingс име на госта, брой нощувки и цена за нощувка. Отпечатай колко струва престоят: за 3 нощувки по 85 € това е 255 €.
Тест