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

Конструктори и this

Проблем

Кафе за 0 €

Създаваш продукт, както в миналия урок, и попълваш полетата ред по ред. Един ред си забравил:

Product coffee = new Product();
coffee.name = "Кафе";
coffee.quantity = 2;
System.out.println(coffee.name + ": " + coffee.price * coffee.quantity + " €");
Изход
Кафе: 0.0 €

Кафето струва 0 €. Компилаторът не се оплаква: от негова гледна точка цената си има стойност, 0. Колкото повече полета има класът, толкова по-лесно е да пропуснеш едно. А продукт без цена не трябва изобщо да може да съществува.

Идеята

Конструктор: без тези данни няма обект

Класът може да каже какво е нужно, за да се създаде обект от него. За това служи конструкторът: специален метод, който се изпълнява при new.

Main.java
class Product {
public String name;
public double price;
public int quantity;
public Product(String name, double price, int quantity) {
this.name = name;
this.price = price;
this.quantity = quantity;
}
}
public class Main {
public static void main(String[] args) {
Product coffee = new Product("Кафе", 7.50, 2);
System.out.println(coffee.name + ": " + coffee.price * coffee.quantity + " €");
}
}
Изход
Кафе: 15.0 €
  • Конструкторът се казва точно като класа: Product.
  • Няма тип на резултата, дори void.
  • Параметрите му са данните, без които продукт няма. Те се подават в скобите на new: new Product("Кафе", 7.50, 2).

Сега няма как да забравиш цената. Ако подадеш два аргумента вместо три, програмата не се компилира.

public Product(String name, double price, int quantity) {
this.name = name;
this.price = price;
this.quantity = quantity;
}
Product coffee = new Product("Кафе", 7.50, 2);
System.out.println(coffee.name + ": " + coffee.price * coffee.quantity + " €");
Стъпка по стъпка, с думи
  1. new заделя нов обект. Полетата му са със стойности по подразбиране.
  2. Изпълнява се конструкторът. Аргументите се копират в параметрите му.
  3. this.name = name: от параметъра в полето на този обект.
  4. Същото за цената и бройката.
  5. Конструкторът свърши и параметрите изчезват. В coffee отива стрелка към готовия обект.
  6. Обектът излиза от new вече попълнен, затова цената не е 0.

Идеята

this: полето на този обект

Вътре в конструктора има две неща с име name: параметърът и полето. Името без нищо пред него е параметърът, защото той е „по-близо“. За полето пишеш this.name.

public Product(String name, double price, int quantity) {
this.name = name;
this.price = price;
this.quantity = quantity;
}

this е обектът, който се създава в момента. this.name = name; значи „в полето name на този обект запиши параметъра name“.

Може параметрите да се казват другояче (productName), и тогава this не е нужно. Но еднаквите имена са обичайни в Java, защото веднага се вижда кой параметър в кое поле отива.

Пробвай

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

Програмата трябва да отпечата „Чай: 3.2 €“. Цената излиза, а името не. На кой ред е грешката?

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

Идеята

А new Product() от миналия урок?

В миналия урок нямаше конструктор, а new Product() работеше. Ако не напишеш конструктор, компилаторът добавя празен, без параметри. Той се казва конструктор по подразбиране и оставя полетата със стойностите им по подразбиране.

Щом напишеш свой конструктор, празният изчезва:

Product empty = new Product();
Грешка при компилиране
error: constructor Product in class Product cannot be applied to given types;

Това е целта: продукт без име и цена вече не може да се създаде. Ако празен конструктор все пак ти трябва, напиши го сам.

Идеята

Няколко конструктора

Повечето продукти в количката са по един брой. Да пишеш 1 всеки път е досадно.

Можеш да дадеш на класа втори конструктор, без бройката. Той стои до първия:

public Product(String name, double price) {
this.name = name;
this.price = price;
this.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) {
this.name = name;
this.price = price;
this.quantity = 1;
}
public Product(String name, double price, int quantity) {
this.name = name;
this.price = price;
this.quantity = quantity;
}
}
Product bread = new Product("Хляб", 1.20);
Product milk = new Product("Мляко", 2.10, 3);
System.out.println(bread.quantity + " " + milk.quantity);
Отговор

Пробвай

Как се казва конструкторът?

Какво трябва да пише на празното място?

class Book {
    public String title;
    public String author;

    public (String title, String author) {
        this.title = title;
        this.author = author;
    }
}

Упражнение

Обекти, създадени цели

Реши задачите в редактора си. Всеки клас получава конструктор с параметри за всички полета.

1. Човек. Клас Person с име и възраст. Създай двама души и отпечатай данните им.

Изход
Мария, 34 г.
Петър, 19 г.

2. Животно. Клас Animal с вид и възраст. Създай котка на 3 и куче на 7 години.

Изход
Вид: котка, възраст: 3
Вид: куче, възраст: 7

3. Танцова стъпка. Клас DanceMove с име и продължителност в секунди. В урока „Поведение“ стъпката ще се научи да се „изпълнява“.

Изход
moonwalk: 5 сек.

Още задачи

  • Книга с конструктор. Препиши Book от миналия урок с конструктор Book(title, author). Колко реда спести в main?
  • Продукт с два конструктора. Product с два конструктора, както в урока. Направи масив { new Product("Хляб", 1.20, 2), new Product("Кафе", 7.50) } и отпечатай името и бройката на всеки: „Хляб x2“, „Кафе x1“. После накарай по-краткия конструктор да вика по-дългия.
  • Резервация. Клас Booking с име на госта, брой нощувки и цена за нощувка. Отпечатай колко струва престоят: за 3 нощувки по 85 € това е 255 €.

Тест

Провери се

1. Кога се изпълнява конструкторът?
2. Какъв тип на резултата се пише пред името на конструктора?
3. В класа има само конструктор Product(name, price). Какво става с new Product()?
4. В конструктора пише this.name = name; Кое е this.name?
5. В класа има два конструктора: с име и цена и с име, цена и бройка. Как се казва това?

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