Конструктори. Конструктори за замовчуванням. Виклик конструкторів з інших конструкторів. Навіщо потрібні конструктори? Що таке конструктор у java

Головна / Контакти

Конструктор – це спеціальний метод, який викликається під час створення нового об'єкта. Не завжди зручно ініціалізувати всі змінні класи під час створення його екземпляра. Іноді простіше, щоб якісь значення були створені за умовчанням під час створення об'єкта. Насправді конструктор необхідний автоматичної ініціалізації змінних.

Конструктор ініціалізує об'єкт безпосередньо під час створення. Ім'я конструктора збігається з ім'ям класу, включаючи регістр, а за синтаксисом конструктор схожий на метод без значення, що повертається.

Private int Cat(); / / Так виглядає метод на ім'я Cat Cat (); // так виглядає конструктор класу Cat

На відміну від методу конструктор ніколи нічого не повертає.

Конструктор визначає дії, які виконуються під час створення об'єкта класу, і є важливою частиною класу. Як правило, програмісти намагаються вказати конструктор. Якщо явного конструктора немає, Java автоматично створить його для використання за замовчуванням. Коли ми реалізовували клас Box, то жодного конструктора не створювали.

Додамо до класу конструктор, який просто встановить початкові значення для коробки.

Class Box ( int width; // ширина коробки int height; // висота коробки int depth; // глибина коробки // Конструктор Box() ( width = 10; height = 10; depth = 10; ) // обчислюємо обсяг коробки int getVolume() ( return width * height * depth; ) )

Ми тимчасово видалили метод setDim()та додали конструктор. Подивимось що вийде:

Box catBox = новий Box(); mInfoTextView.setText("Обсяг коробки:" + catBox.getVolume());

Програма виведе об'єм коробки, хоча ми не ставили жодних розмірів для неї. Завдяки конструктору будь-яка коробка, що створюється, матиме якийсь зафіксований обсяг.

Звичайно, ви можете повернути назад метод setDim()(див. статтю про класи) та встановити свої розміри для коробки:

Box catBox = новий Box(); // Встановимо свої розміри для коробки catBox.setDim (10, 20, 30); mInfoTextView.setText("Обсяг коробки:" + catBox.getVolume());

Тепер вам має бути ясно, що коли після ключового слова newми пишемо ім'я класу зі дужками, то насправді ми викликаємо конструктор класу.

Виникає питання - але спочатку при створенні класу ми не створювали конструктор, однак код new Box()працював. Справа в тому, що якщо конструктор не визначений явно, Java створить конструктор, який буде використовуватися за замовчуванням. У цьому випадку він просто надасть усім змінним нульові значення. Якщо ви створили конструктор, то конструктор за замовчуванням використовуватися не буде.

Подібно до будь-якого методу, у конструктора можуть бути аргументи. У аргументах конструктора передаються параметри ініціалізації об'єкта. Наприклад, якщо у класу Catє конструктор, який отримує як аргумент ціле число, що позначає вік кота, то об'єкти Catбудуть створюватися таким чином:

Cat Cat = New Cat (8); // Коту 8 років

Якщо Cat(int)є єдиним конструктором класу, то компілятор не дозволить створювати об'єкти Catбудь-яким іншим способом.

Однак повернемося до коробок для котів. Створений нами конструктор не дуже корисний, тому що створює однакові коробки. Створимо конструктор з параметрами у класі Boxта закоментуйте перший конструктор без параметрів:

// Другий конструктор Box(int ​​w, int h, int d) (width = w; height = h; depth = d;)

Якщо клас містить один конструктор з параметрами, вам доведеться обов'язково вказати значення при оголошенні класу:

// Це конструктор тепер не допустимо // Box catBox = new Box(); // У конструкторі необхідно вказати значення розмірів коробки Box catBox = new Box(100, 200, 100); mInfoTextView.setText("Обсяг коробки:" + catBox.getVolume());

До речі, з таким конструктором метод setDim()нам не потрібен. Ми можемо встановити розміри коробки відразу в конструкторі. Так як швидше за все коробка стала і не змінює своїх розмірів, то метод, мабуть, зайвий. Але якщо ми мінятимемо розміри коробки, то метод доведеться залишити.

Клас може мати кілька конструкторів. Зніміть коментар з першого конструктора та створіть дві коробки - коробку за замовчуванням та велику коробку.

Box defaultBox = новий Box(); mInfoTextView.setText("Обсяг стандартної коробки: " + defaultBox.getVolume()); Box bigBox = новий Box(100, 200, 200); mInfoTextView.append("\nОбсяг великої коробки: " + bigBox.getVolume());

Тобто, бачимо, що конструктори підтримують навантаження, як і методи.

Наприклад, ми можемо створити ще один конструктор спеціально для коробки у вигляді куба, де всі сторони рівні:

// Третій конструктор для куба Box(int ​​len) (width = height = depth = len;)

Обчислюємо розмір куба:

Box cube = новий Box(5); int vol = cube.getVolume(); mInfoTextView.setText("Обсяг куба:" + vol);

Використовуємо об'єкт як параметри

Ми поки що використовували як параметри в конструкторах прості типи. Але можна передати об'єкт самого класу. Додамо ще один конструктор:

// Використовуємо об'єкт типу Box Box(Box ob) (width = ob.width; height = ob.height; depth = ob.depth; )

У коді програми можна скористатися конструктором так:

Box box1 = new Box(100, 200, 100); Box cloneBox = новий Box(box1); int vol = cloneBox.getVolume(); mInfoTextView.setText("Обсяг коробки:" + vol);

Клас Box (вихідник)

package uk.alexanderklimov.box; class Box ( int width; // ширина коробки int height; // висота коробки int depth; // глибина коробки // Конструктор Box() ( width = 10; height = 10; depth = 10; ) // Другий конструктор Box( int w, int h, int d) (width = w; height = h; depth = d;) // Третій конструктор для куба Box(int ​​len) (width = height = depth = len; ) // Використовуємо об'єкт типу Box Box(Box ob) (width = ob.width; height = ob.height; depth = ob.depth; ) // обчислюємо обсяг коробки int getVolume() ( return width * height * depth; ) // встановлюємо розміри коробки void setDim (int w, int h, int d) ( width = w; height = h; depth = d; ) )

Виклик перевантажених конструкторів через this()

Маючи справу з перевантаженими конструкторами, зручно один конструктор викликати з іншого через ключове слово this. При виконанні конструктора this()спочатку виконується перевантажений конструктор, який відповідає списку параметрів. Потім виконуються оператори, що усередині вихідного конструктора, якщо такі існують. Виклик конструктора this()має бути першим оператором у конструкторі.

Для початку створимо клас, який не використовує конструктор this(), щоб зрозуміти різницю.

Class Cat (int age; int birthday; // Ініціалізуємо змінні явно Cat(int i, int j) (age = i; birthday = j;) // Ініціалізуємо змінні одним і тим значенням Cat(int i) (age = i; birthday = i; ) // Надамо значення за замовчуванням 0 Cat() ( age = 0; birthday = 0; ) )

Ми створили клас із трьома конструкторами. Перепишемо клас, використовуючи конструктор this().

Class Cat( int age; int birthday; // Ініціалізуємо змінні явно Cat(int i, int j) ( age = i; birthday = j; ) // Ініціалізуємо змінні одним і тим значенням Cat(int i) ( this(i, i);// викликається Cat(i, i);

У нас тепер лише один конструктор, який надає значення полям – Cat(int, int). Що відбувається при виконанні оператора:

Cat Cat = New Cat (8);

Виклик конструктора Cat(8)приводить до виконання конструктора this(8, 8), що рівнозначно виклику конструктора Cat(8, 8).

Що відбувається при виконанні оператора:

Cat cat2 = New Cat ();

В цьому випадку викликається конструктор this(0)що призводить до виконання конструктора Cat(0)оскільки саме ця версія конструктора підходить за списком параметрів. При цьому конструктор Cat(0)по суті викликає конструктор Cat(0, 0).

Використання перевантажених конструкторів через конструктор this()дозволяє виключити дублювання коду, зменшуючи час завантаження класів.

Але слід бути обережним, тому що конструктори, які викликають конструктор this(), Виконуються трохи повільніше.

Закритий конструктор

Іноді клас створюється лише зберігання якихось статичних полів і статичних методів. Таким класам прийнято давати імена Utilsале це не обов'язково. Такому класу не потрібен конструктор, але якщо автор класу його не створив, система сама створить конструктор за замовчуванням. Такий конструктор не має сенсу, а також може стати джерелом помилок. Щоб захиститися від подібної проблеми, ви самі явно повинні створити пустий конструктор і зробити його закритим.

Public class Utils ( private Utils() ( throw new AssertionError(); ) ... //Ваш правильний код // Неправильний код, тільки для демонстрації! public static void someMethod()( Utils utils = new Utils(); toString(); ) )

Рядок throw new AssertionError()не є обов'язковою, але вона допоможе виявити помилку, якщо ви викличете конструктор у самому класі. Компілятор пропустить такий варіант, але програма завершиться помилкою.

Utils.someMethod(); // програма закриється з помилкою

Підклас для цього класу ви створити не зможете.

Вітаю! Сьогодні ми розберемо дуже важливу тему щодо наших об'єктів. Тут без перебільшення можна сказати, що цими знаннями ти користуватимешся кожен день у реальній роботі! Ми поговоримо про конструкторах.

Ти, можливо, чуєш цей термін вперше, але насправді користувався конструкторами, тільки сам не помічав цього:) Ми переконаємося в цьому пізніше.

Що таке конструктори та навіщо вони потрібні?

Розглянемо два приклади. public class Car ( String model; int maxSpeed; public static void main (String args) ( Car bugatti = new Car () ; bugatti. model = "Bugatti Veyron" ; bugatti. maxSpeed ​​= 407 ; ) ) Ми створили наш автомобіль і встановили для нього модель та максимальну швидкість. Однак у реальному проекті об'єкт Car явно буде не 2 поля. А, наприклад, 16 полів! public class Car (String model; //модель int maxSpeed; //максимальна швидкість//об'єм двигуна//прізвище власника// число місць у салоні String salonMaterial; //матеріал салону boolean insurance; // Чи застрахована//країна виробник int trunkVolume; //обсяг багажника int accelerationTo100km; public static void main (String args) ( Car bugatti = new Car () ; bugatti. color = "blue" ; bugatti. accelerationTo100km = 3 ; bugatti. engineVolume = 6.3 ; bugatti. manufacturerCountry = "Italy" ; bugatti. Amigo" ; bugatti. yearOfIssue = 2016 ; bugatti. insurance = true ; bugatti. price = 2000000 ; bugatti. isNew = false ; bugatti. placesInTheSalon = 2 ; bugatti. max ; Ми створили новий об'єкт Car. Одна проблема: полів у нас 16, а проініціалізували ми лише 12! Спробуй за кодом знайти ті, які ми забули! Не так просто, так? У такій ситуації програміст може легко помилитися та пропустити ініціалізацію якогось поля. У результаті поведінка програми стане помилковою: public class Car (String model; // модель int maxSpeed; //максимальна швидкість int wheels; //ширина дисків double engineVolume; //об'єм двигуна String color; //Колір int yearOfIssue; // Рік випуску String ownerFirstName; //ім'я власника String ownerLastName; //прізвище власника long price; //Ціна boolean isNew; //Нова чи ні int placesInTheSalon; // число місць у салоні String salonMaterial; //матеріал салону boolean insurance; // Чи застрахована String manufacturerCountry; //країна виробник int trunkVolume; //обсяг багажника int accelerationTo100km; //розгін до 100 км/год на секундах public static void main (String args) ( Car bugatti = new Car () ; bugatti. color = "blue" ; bugatti. accelerationTo100km = 3 ; bugatti. engineVolume = 6.3 ; bugatti. manufacturerCountry = "Italy" ; bugatti. Amigo" ; bugatti. yearOfIssue = 2016 ; bugatti. insurance = true ; bugatti. price = 2000000 ; bugatti. isNew = false ; bugatti. placesInTheSalon = 2 ; bugatti. max Ve = 47 out.println ( "Модель Bugatti Veyron. Об'єм двигуна - "+ Bugatti. engineVolume+", багажника -"+bugatti. trunkVolume + ", салон зроблений з "+ Bugatti. salonMaterial + ", ширина дисків -"+ Bugatti. wheels + ". Була придбана у 2018 році паном"+ Bugatti. ownerLastName); ) ) Виведення в консоль: Модель Bugatti Veyron. Об'єм двигуна - 6.3, багажника - 0, салон зроблений з null, ширина дисків - 0. Була придбана у 2018 році паном nullВашому покупцеві, який віддав 2 мільйони доларів за машину, явно не сподобається, що його назвали “ паном null”! А якщо серйозно, у результаті в нашій програмі виявився некоректно створений об'єкт - машина із шириною дисків 0 (тобто взагалі без дисків), відсутнім багажником, салоном, зробленим з невідомого матеріалу, та ще й комусь, що належить незрозуміло. Можна тільки уявити, як така помилка може "вистрілити" під час роботи програми! Нам треба якось уникнути таких ситуацій. Треба щоб у нашій програмі було обмеження: при створенні нового об'єкта машини для нього завждиповинні бути вказані, наприклад, модель та максимальна швидкість. Інакше – не дозволяти створення об'єкта. З цим завданням легко справляються функції-конструктори. Вони отримали свою назву не так. Конструктор створює своєрідний "каркас" класу, якому кожен новий об'єкт класу має відповідати. Давай для зручності повернемося до простішого варіанту класу Car з двома полями. З урахуванням наших вимог, конструктор для класу Car буде виглядати так: public Car (String model, int maxSpeed) ( this . model = model; this . maxSpeed ​​= maxSpeed; ) А створення об'єкта тепер виглядає так: public static void main (String args ) ( Car bugatti = new Car ( " Bugatti Veyron " , 407 ) ; ) Зверніть увагу, як створюється конструктор. Він схожий на звичайний метод, але у нього немає типу значення, що повертається. При цьому в конструкторі вказується назва класу, також з великої літери. У нашому випадку - Car. Крім того, у конструкторі використовується нове для тебе. this. "this" по-англійськи - "цей, цього". Це слово свідчить про конкретний предмет. Код у конструкторі: public Car (String model, int maxSpeed) (this. model = model; this. конструктора. maxSpeed ​​для цієї машини (яку ми створюємо) = аргументу maxSpeed ​​, який вказаний у конструкторі." Так і сталося: public class Car (String model; int maxSpeed; public Car (String model, int maxSpeed) (this.model=model;this.maxSpeed=maxSpeed;)) Car ( " Bugatti Veyron " , 407 ) ; System. out. println (bugatti. model) ; System. Bugatti Veyron 407Конструктор успішно надав потрібні значення. Ти, можливо, помітив, що конструктор дуже нагадує звичайний метод! Так воно і є: конструктор - це метод, тільки трохи специфічний:) Так само як у метод, наш конструктор ми передали параметри. І так само як виклик методу, виклик конструктора не спрацює, якщо їх не вказати: public class Car (String model; int maxSpeed; public Car (String model, int maxSpeed) (this. Public static void main (String args) (Car bugatti = new Car(); //помилка!)) Бачиш, конструктор зробив те, чого ми намагалися досягти. Тепер не можна створити машину без швидкості чи моделі! На цьому подібність конструкторів та методів не закінчується. Так само, як і методи, конструктори можна перевантажувати. Уяви, що в тебе вдома живуть 2 коти. Одного з них ти взяв ще кошеням, а другого приніс додому з вулиці вже дорослим і не знаєш точно, скільки йому років. Отже, наша програма повинна вміти створювати котів двох видів – з ім'ям та віком для першого кота, і лише з ім'ям – для другого кота. Для цього ми перевантажимо конструктор: public class Cat (String name; int age; //для першого кота //Для другого кота public Cat (String name) ( this . name = name; ) public static void main (String args) ( Cat barsik = new Cat ("Barsik" , 5 ) ; Cat streetCatNamedBob = new Cat ( "Bob" ) ; ) ) До Спочатку конструктору з параметрами "ім'я" і "вік" ми додали ще один, тільки з ім'ям. Так само ми перевантажували методи у минулих уроках. Тепер ми успішно можемо створити обидва варіанти котів:)

Пам'ятаєш, на початку лекції ми говорили, що ти вже користувався конструкторами, але сам не помічав цього? Так і є. Справа в тому, що у кожного класу в Java є так званий конструктор за замовчуванням. У нього немає жодних аргументів, але він спрацьовує щоразу під час створення будь-якого об'єкта будь-якого класу. На перший погляд це непомітно. Ну, створили об'єкт і створили, де тут робота конструктора? Щоб це побачити, давай прямо руками напишемо для класу Cat порожній конструктор, а всередині нього виведемо якусь фразу в консоль. Якщо вона виведеться, то конструктор відпрацював. public class Cat ( public Cat () ( System. out. println ("Створили кота!" ) ; ) public static void main (String args) ( Cat barsik = new Cat () ; //Ось тут спрацював конструктор за замовчуванням } } Виведення в консоль: Створили кота! Ось і підтвердження! За замовчуванням конструктор завжди незримо присутній у твоїх класах. Але тобі треба знати ще одну його особливість. Дефолтний конструктор зникає із класу, коли ти створюєш якийсь конструктор із аргументами.Доказ цього насправді ми вже бачили вище. Ось у цьому коді: public class Cat (String name; int age; public Cat (String name, int age) (this.name = name; this.age = age;)) new Cat () ; //помилка! ) ) Ми не змогли створити кота без імені та віку, тому що визначили конструктор для Cat: рядок + число. Дефолтний конструктор одразу після цього зникіз класу. Тому обов'язково запам'ятай: якщо тобі у твоєму класі потрібно кілька конструкторів, включаючи порожній, його потрібно створити окремо. Наприклад, ми створюємо програму для ветеринарної клініки. Наша клініка хоче робити добрі справи та допомагати бездомним котикам, про які ми не знаємо ні імені, ні віку. Тоді наш код має виглядати так: public class Cat (String name; int age; //для домашніх котів Public Cat (String name, int age) ( this . name = name; this . age = age; ) //для вуличних котів public Cat () ( ) public static void main (String args) ( Cat barsik = новий Cat ( " Barsik " , 5 ) ; Cat streetCat = новий Cat () ; ) ) Тепер, коли ми явно прописали конструктор за замовчуванням, ми можемо створювати котів обох типів:) Для конструктора (як і будь-якого методу) дуже важливий порядок дотримання аргументів.Поміняємо у нашому конструкторі аргументи імені та віку місцями. public class Cat (String name; int age; public Cat (int age, String name) ( this . name = name; this . age = age; ) public static void main (String args) ( Cat barsik = new Cat ("Барсик ", 10); // Помилка!)) Помилка! Конструктор чітко описує: при створенні об'єкта Cat йому мають бути передані число та рядок, саме в такому порядку. Тому наш код не спрацьовує. Обов'язково запам'ятай це і врахуй при створенні своїх власних класів: public Cat (String name, int age) (this.name = name; this.age = age;) public Cat (int age, String name) (this.age = age; this .name = name;) Це два абсолютно різних конструктора! Якщо висловити в одному реченні відповідь на запитання "Навіщо потрібен конструктор?", можна сказати: для того, щоб об'єкти завжди знаходилися у правильному стані. Коли ти використовуєш конструктори, всі твої змінні будуть коректно проініціалізовані, і в програмі не буде машин зі швидкістю 0 та інших неправильних об'єктів. Їхнє використання дуже вигідне насамперед для самого програміста. Якщо ти ініціалізуватимеш поля самостійно, великий ризик щось пропустити і помилитися. А з конструктором такого не буде: якщо ти передав у нього не всі потрібні аргументи або переплутав їх типи, компілятор одразу випустить помилку. Окремо варто сказати про те, що всередину конструктора не варто поміщати логіку твоєї програми. Для цього у твоєму розпорядженні є методи, В яких ти можеш описати весь потрібний тобі функціонал. Давай подивимося, чому логіка в конструкторі - це погана ідея: public class CarFactory (String name; int age; int carsCount; this .carsCount = carsCount;System.out.println ( "Вона була заснована" "У середньому вона виробляє"+ (this . carsCount / this . age) + "Машин на рік"); ) public static void main ( String args ) ( CarFactory ford = new CarFactory, що описує фабрику з виробництва автомобілів Усередині конструктора ми ініціалізуємо всі поля, і сюди поміщаємо логіку: виводимо в консоль деяку інформацію про фабрику. Здавалося б – нічого поганого в цьому немає, програма чудово відпрацювала. Виведення в консоль: Наша автомобільна фабрика називається Ford Вона була заснована 115 років тому. За цей час на ній було вироблено 50000000 автомобілів.Але насправді ми заклали міну уповільненої дії. І подібний код може дуже легко спричинити помилки. Уявімо, що тепер ми говоримо що не про Ford, а про нову фабрику "Amigo Motors", яка існує менше року і виробила 1000 машин: public class CarFactory (String name; int age; int carsCount; age, int carsCount) (this. name = name; this. age = age; this. carsCount = carsCount; System. out. println ( "Наша автомобільна фабрика називається "+ this . name); System. out. println ( "Вона була заснована"+ this . age + "років тому"); System. out. println ( "За цей час на ній було зроблено"+ this . carsCount + "автомобілів"); System. out. println ( "У середньому вона виробляє"+ (this . carsCount / this . age) + "Машин на рік"); ) public static void main (String args) ( CarFactory ford = new CarFactory ( " Amigo Motors " , 0 , 1000 ) ; ) ) Висновок в консоль: Наша автомобільна фабрика називається Amigo Motors Exception in thread "main" java.lang.ArithmeticException: / by zero Вона була заснована 0 років тому За цей час на ній було вироблено 1000 автомобілів на CarFactory. (CarFactory.java:15) at CarFactory.main(CarFactory.java:23) Process finished with exit code 1Приїхали! Програма завершилася з якоюсь незрозумілою помилкою. Спробуєш здогадатися, у чому причина? Причина – у логіці, яку ми помістили у конструктор. А саме - ось у цьому рядку: System. out. println ( "У середньому вона виробляє"+ (this . carsCount / this . age) + "Машин на рік"); Тут ми виконуємо обчислення та ділимо кількість вироблених машин на вік фабрики. А оскільки наша фабрика нова (тобто їй 0 років) – у результаті виходить розподіл на 0, який у математиці заборонено. В результаті програма завершується помилково. Як же нам варто було вчинити?Винести всю логіку в окремий метод і назвати його, наприклад, printFactoryInfo() . Як параметр можна передати об'єкт CarFactory . Туди ж можна помістити всю логіку, і заодно - обробку можливих помилок, на зразок нашої з нулем років. Кожному своє. Конструктори необхідні коректного завдання стану об'єкта.Для бізнес-логіки ми маємо методи. Не варто змішувати одне з одним. Ось кілька корисних посилань, де ти можеш додатково почитати про конструкторів:

Конструктор – це подібна методом структура, призначення якої полягає у створенні екземпляра класу. Характеристики конструктора:
  • Ім'я конструктора має співпадати з ім'ям класу (за домовленістю, перша літера - велика, зазвичай іменник);
  • Конструктор є у будь-якому класі. Навіть якщо ви його не написали, компілятор Java сам створить стандартний конструктор (default constructor), який буде порожнім і не робить нічого, крім виклику конструктора суперкласу.
  • Конструктор подібний до методу, але не є методом, він навіть не вважається членом класу. Тому його не можна успадковувати чи перевизначити у підкласі;
  • Конструктори не успадковуються;
  • Конструкторів може бути дещо в класі. І тут конструктори називають перевантаженими;
  • Якщо в класі не описаний конструктор, компілятор автоматично додає код конструктор без параметрів;
  • Конструктор немає повертаного типу, їм може бути навіть тип void , якщо повертається тип void , це вже конструктор а метод, попри збіг з ім'ям класу.
  • У конструкторі допускається оператор return, але тільки порожній, без будь-якого значення, що повертається;
  • У конструкторі допускається застосування модифікаторів доступу, можна задати один із модифікаторів: public, protected, private або без модифікатора.
  • Конструктор не може мати модифікаторів abstract, final, native, static або synchronized;
  • Ключове слово цього посилається на інший конструктор у цьому ж класі. Якщо використовується, то звернення має бути першим рядком конструктора;
  • Ключове слово super викликає конструктор батьківського класу. Якщо використовується, звернення до нього має бути першим рядком конструктора;
  • Якщо конструктор не здійснює виклик конструктора super класу-предка (з аргументами або без аргументів), компілятор автоматично додає код виклику конструктора класу-предка без аргументів;

Конструктор за замовчуванням

Конструктор є у будь-якому класі. Навіть якщо його не написали, компілятор Java сам створить конструктор за замовчуванням (default constructor). Цей конструктор порожній і робить нічого, крім виклику конструктора суперкласса. Тобто. якщо написати: public class Example () то це еквівалентно написанню: public class Example (Example() (super;)) У даному випадку явно класу предка не вказано, а за замовчуванням всі класи Java успадковують клас Object тому викликається конструктор класу Object. Якщо класі визначено конструктор з параметрами, а перевантаженого конструктора без параметрів немає, то виклик конструктора без параметрів є помилкою. Тим не менш, Java, починаючи з версії 1.5, можна використовувати конструктори з аргументами змінної довжини. І якщо є конструктор, що має аргумент змінної довжини, то виклик конструктора за промовчанням не буде помилкою. Не буде тому, що аргумент змінної довжини може бути пустим. Наприклад, наступний приклад не компілюватиметься, проте якщо розкоментувати конструктор з аргументом змінної довжини, то компіляція і запуск пройдуть успішно і в результаті роботи рядка коду DefaultDemo dd = new DefaultDemo() ; викличеться конструктор DefaultDemo (int ... v). Природно, що в цьому випадку необхідно скористатися JSDK 1.5. Файл DefaultDemo.java class DefaultDemo ( DefaultDemo (String s) ( System. out. print ("DefaultDemo(String)" ) ; ) /* DefaultDemo(int ... v) ( System.out.println("DefaultDemo(int ...)"); ) */ public static void main (String args ) ( DefaultDemo dd = new DefaultDemo () ; ) ) Результат виведення програми при розкоментованому конструкторі: DefaultDemo (int . . . ) Однак, у поширеному випадку, коли в класі взагалі не визначено жодного конструктора, виклик стандартного конструктора (без параметрів) буде обов'язковим явищем, оскільки підстановка конструктора за замовчуванням відбувається автоматично.

Під час створення об'єкта послідовно виконуються такі дії:
  • Шукається клас об'єкта серед класів, що вже використовуються в програмі. Якщо його немає, він шукається у всіх доступних програмі каталогах і бібліотеках. Після виявлення класу в каталозі або бібліотеці виконується створення та ініціалізація статичних полів класу. Тобто. для кожного класу статичні поля ініціалізуються лише один раз.
  • Виділяється пам'ять під об'єкт.
  • Виконується ініціалізація полів класу.
  • Відпрацьовує конструктор класу.
  • Формується посилання на створений та ініціалізований об'єкт. Це і є значенням висловлювання, що створює об'єкт. Об'єкт може бути створений за допомогою виклику методу newInstance() класу java.lang.Class . І тут використовується конструктор без списку параметрів.

Перевантаження конструкторів

Конструктори одного класу можуть мати однакове ім'я та різну сигнатуру. Така властивість називається поєднанням чи перевантаженням (overloading). Якщо клас має кілька конструкторів, то є перевантаження конструкторів.

Параметризовані конструктори

Сигнатура конструктора – це і типи параметрів, і навіть послідовність їх типів у списку параметрів конструктора. Тип результату, що повертається, не враховується. Конструктор не повертає жодних параметрів. Це становище пояснює у сенсі, як Java розрізняє перевантажені конструктори чи методи. Java розрізняє перевантажені методи не за типом, що повертається, а за кількістю, типами і послідовністю типів вхідних параметрів. Конструктор не може повертати навіть тип void, інакше він перетвориться на звичайний метод, навіть не дивлячись на схожість з ім'ям класу. Наступний приклад показує це. Файл VoidDemo.java class VoidDemo ( /** * Це конструктор */ VoidDemo () ( System. out. println ("Constructor" ) ; ) void VoidDemo () ( System. out. println ("Method" ) ; ) ) ) В результаті програма виведе: Constructor Це ще раз доводить, що конструктором є метод без параметрів, що повертаються. Тим не менш, для конструктора можна задати один із трьох модифікаторів public, private або protected. І приклад тепер буде виглядати так: Файл VoidDemo2.java class VoidDemo2 ( /** * Це конструктор */ public VoidDemo2 () ( System. out. println ("Constructor" ) ; ) /** * А це вже звичайний метод, навіть не дивлячись на схожість з * ім'ям класу, оскільки є тип void */ private void VoidDemo2 () ( System. out. println ("Method" ) ; ) У конструкторі дозволяється записувати оператор return , але тільки порожній, без жодного значення, що повертається. Файл ReturnDemo.java class ReturnDemo ( /** * У конструкторі допускається використання оператора *return без параметрів. */ public ReturnDemo () ( System. out. println ("Constructor" ) ; return ; ) public static void main (String s )

Конструктори, параметризовані аргументами змінної довжини

У Java SDK 1.5 з'явився довгоочікуваний інструмент - аргументи змінної довжини для конструкторів та методів (variable-length arguments). До цього змінне кількість документів оброблялося двома незручними методами. Перший був розрахований на те, що максимальна кількість аргументів обмежена невеликою кількістю і заздалегідь відома. У такому випадку можна було створювати версії методу, що перевантажуються, по одній на кожен варіант списку передаються в метод аргументів. Другий спосіб розрахований на невідоме заздалегідь і велику кількість аргументів. І тут аргументи поміщалися в масив, і це масив передавався методу. Аргументи змінної довжини найчастіше задіяні у наступних маніпуляціях із ініціалізаціями змінних. Відсутність деяких із очікуваних аргументів конструктора чи методу зручно замінювати значеннями за промовчанням. Аргумент змінної довжини є масивом, і обробляється як масив. Наприклад, конструктор для класу Checking зі змінним числом аргументів буде виглядати так: будуть зберігатися в масиві, значення посилання на яке міститься в змінній n. Конструктор може викликатися з різним числом аргументів, включаючи їхню повну відсутність. Аргументи автоматично поміщаються масив і передаються через n. У разі відсутності аргументів довжина масиву дорівнює 0. До списку параметрів поряд з аргументами змінної довжини можуть бути включені обов'язкові параметри. У цьому випадку параметр, що містить змінну кількість аргументів, повинен обов'язково бути останнім у списку параметрів. Наприклад: class Checking (public Checking (String s, int...n) ()) Цілком очевидне обмеження стосується кількості параметрів зі змінною довжиною. У списку параметрів має бути лише один параметр змінної довжини. За наявності двох параметрів змінної довжини компілятор неможливо визначити, де закінчується один параметр і починається інший. Наприклад: class Checking (public Checking (String s, int . . n, double . . . d) // ПОМИЛКА! ( ) ) Файл Checking.java Наприклад, є апаратура, здатна розпізнавати номери автомобілів і запам'ятовувати номери квадратів місцевості, де побував кожен із автомобілів за день. Необхідно із загальної маси зафіксованих автомобілів відібрати ті, які протягом дня побували у двох заданих квадратах, скажімо 22 та 15, згідно з картою місцевості. Цілком природно, що автомобіль може протягом дня побувати в багатьох квадратах, а може лише в одному. Очевидно, що кількість відвідуваних квадратів обмежена фізичною швидкістю автомобіля. Складемо невелику програму, де конструктор класу буде приймати як аргументи номер автомобіля як обов'язковий параметр та номери відвіданих квадратів місцевості, число яких може бути змінним. Конструктор перевірятиме, чи не з'явився автомобіль у двох квадратах, якщо з'явився, то вивести його номер на екран.

Передача параметрів у конструктор

У мовах програмування існує переважно два види параметрів:
  • основні типи (примітиви);
  • посилання на об'єкти.
Термін виклик за значенням (call by value) означає, що конструктор отримує значення, передане йому модулем, що викликає. На противагу цьому, виклик за посиланням (call by reference) означає, що конструктор отримує від модуля, що викликає, адресу змінної. У мові Java використовується лише виклик за значенням. За значенням параметра та значенням посилання параметра. Java не використовує виклик за посиланням для об'єктів (хоча багато програмістів та авторів деяких книг це стверджують). Параметри під час передачі об'єктів у Java здійснюються не за посиланням, а за значенням посилання на об'єкти! У будь-якому випадку конструктор отримує копії значень усіх параметрів. Конструктор не може робити зі своїми вхідними параметрами:
  • конструктор неспроможна змінювати значення вхідних параметрів основних (примітивних) типів;
  • конструктор неспроможна змінювати посилання вхідних параметрів;
  • конструктор неспроможна перепризначати посилання вхідних параметрів нові об'єкти.
Конструктор може робити зі своїми вхідними параметрами:
  • змінювати стан об'єкта, що передається як вхідний параметр.
Наступний приклад доводить, що Java вхідні параметри для конструктора передаються за значенням посилання на об'єкт. Також у цьому прикладі відображено те, що конструктор не може змінювати посилання вхідних параметрів, а фактично змінює посилання копій вхідних параметрів. Файл Empoyee.java class Employee ( Employee (String x, String y) ( String temp = x; x = y; y = temp; ) public static void main (String args ) ( String name1 = new String ("Alice" ) ; String name2 = New String ("Mary") ; Employee a = New Employee (name1, name2) ; System. out. println ("name1=" + name1) ; System. ) Результат виведення програми: name1= Alice name2= Mary Якби у мові Java передачі об'єктів як параметрів використовувався виклик за посиланням, то конструктор поміняв у цьому прикладі місцями name1 і name2 . Насправді конструктор не замінить місцями об'єктні посилання, що зберігаються в змінних name1 і name2. Це свідчить, що параметри конструктора ініціалізуються копіями цих посилань. Потім конструктор міняє місцями копії. По завершенні роботи конструктора змінні x та y знищуються, а вихідні змінні name1 і name2 продовжують посилатися на колишні об'єкти.

Зміна параметрів, що передаються конструктору.

Конструктор не може модифікувати передані параметри основних типів. Однак конструктор може модифікувати стан об'єкта, що передається як параметр. Наприклад, розглянемо таку програму: Файл Salary1.java class Salary1 (Salary1 (int x) (x = x * 3; System. out. println ("x="+x);)) public static void main (String args) (int value = 1000 ; Salary1 s1 = new Salary1 (value) ; System. Результат виведення програми: x= 3000 value= 1000 Вочевидь, такий спосіб не змінить параметр основного типу. Тому після виклику конструктора значення змінної value залишається рівним 1000. По суті відбувається три дії:
  1. Змінна x ініціалізується копією значення параметра value (тобто числом 1000).
  2. Значення змінної x потроюється - тепер воно дорівнює 3000. Однак значення змінної value залишається рівним 1000.
  3. Конструктор завершує свою роботу і змінна x більше не використовується.
У наступному прикладі зарплата співробітника успішно потроюється, оскільки як параметр методу передається значення посилання об'єкта. Файл Salary2.java class Salary2 ( int value = 1000 ; Salary2 () ( ) Salary2 (Salary2 x) ( x. value = x. value * 3 ; ) public static void main (String args ) Salary2 s2 = New Salary2 (s1) System."s1.value="+ s1. value); System. out. println ("s2.value="+ s2. value); ) Результат виведення програми: s1. value=3000 s2. value= 1000 Як параметр використовується значення посилання на об'єкт. За виконання рядка Salary2 s2 = new Salary2(s1) ; конструктору Salary2(Salary x) передасться значення посилання об'єкт змінної s1 , і конструктор фактично потроїть зарплату для s1.value , оскільки копія (Salary x) , створювана всередині конструктора свідчить про об'єкт змінної s1 .

Конструктори параметризовані примітивами.

Якщо у параметрах перевантаженого конструктора використовується примітив, який може бути звужений (наприклад int<- double), то вызов метода со суженным значением возможен, несмотря на то, что метода, перегруженного с таким параметром нет. Например: Файл Primitive.java class Primitive { Primitive (double d) { d = d + 10 ; System. out. println (!}"d=" + d) ; } public static void main (String args ) { int i = 20 ; Primitive s1 = new Primitive (i) ; } } Результат виведення програми: d= 30.0 Незважаючи на те, що в класі Primitive відсутній конструктор, який має параметр типу int , відпрацює конструктор з вхідним параметром double . Перед викликом конструктора змінна i буде розширена від типу int до double. Зворотний варіант, коли змінна i була б типу double, а конструктор був би тільки з параметром int, у цій ситуації призвів би до помилки компіляції.

Виклик конструктора та оператор new

Конструктор завжди викликається оператором new. При виклику конструктора оператором new конструктор завжди формує посилання на новий об'єкт. Примусити конструктор сформувати замість посилання на новий об'єкт посилання на існуючий об'єкт не можна, крім підстановки об'єкта, що десеріалізується. А з оператором new сформувати замість посилання на новий об'єкт посилання на існуючий об'єкт не можна. Наприклад: Файл Salary3.java class Salary3 ( int value = 1000 ; Salary3 () ( ) Salary3 (Salary3 x) ( x. value = x. value * 3 ; ) public static void main (String args ) ( Salary3 s1 = new Salary3 () ; System. out. println ("First object creation: " + s1. value) ; out.println (+ s1. value) ; Salary3 s3 = new Salary3 (s1) ; System. "What"s happend with first object?:"+ s1. value); ) Результат виведення програми: First object creation: 1000 Second object creation: 1000 What"s happend with first object? : 3000 Third object creation: 1000 What"s happend with first object? : 9000 Спочатку за допомогою рядка Salary3 s1 = new Salary3() ; створюється новий об'єкт. Далі, якщо за допомогою рядка Salary3 s2 = new Salary3(s1) ; або рядки Salary3 s3 = New Salary3(s1) ; можна створити посилання на вже існуючий об'єкт, то s1.value s2.value і s3.value зберігали б однакове значення 1000 . Насправді рядок Salary3 s2 = new Salary3(s1) ; створиться новий об'єкт для змінної s2 і зміниться стан об'єкта для змінної s1 через передачу свого значення посилання на об'єкт, в параметрі конструктора. У цьому вся можна переконатися за результатами вывода. А під час виконання рядка Salary3 s3 = new Salary3(s1) ; створиться НОВИЙ об'єкт для змінної s3 і знову зміниться стан об'єкта для змінної s1.

Конструктори та блоки ініціалізації, послідовність дій під час виклику конструктора

У розділі Створення об'єкта та конструктори перераховані дії загального характеру, які виробляються під час створення об'єкта. Серед них сполучаються процеси ініціалізації полів класу та відпрацювання конструктора класу, які у свою чергу теж мають внутрішній порядок:
  1. Усі поля даних ініціалізуються своїми значеннями, передбаченими за промовчанням (0, false чи null).
  2. Ініціалізатори всіх полів та блоки ініціалізації виконуються в порядку їх перерахування в оголошенні класу.
  3. Якщо першому рядку конструктора викликається інший конструктор, то виконується викликаний конструктор.
  4. Виконується тіло конструктора.
Конструктор має відношення до ініціалізації, оскільки Java існує три способи ініціалізації поля в класі:
  • присвоїти значення в оголошенні;
  • присвоїти значення в блоці ініціалізації;
  • задати його значення у конструкторі.
Звичайно, потрібно організувати код ініціалізації так, щоб у ньому було легко розібратися. Як приклад наведено наступний клас: class Initialization ( int i; short z = 10 ; static int x; static float y; static ( x = 2000 ; y = 3.141 ; ) Initialization () ( System. out. println ("i= " + i) ; System. out. println ("z=" + z) ; z = 20 ; ініціалізуються статичні змінні x та y значеннями за умовчанням. Далі виконується статичний блок ініціалізації. Потім проводиться ініціалізація змінної i значенням за умовчанням та ініціалізується змінна z. Далі у роботу вступає конструктор. Виклик конструкторів класу повинен залежати від порядку оголошення полів. Це може призвести до помилок.

Конструктори та успадкування

Конструктори не успадковуються. Наприклад: public class Example ( Example () ( ) public void sayHi () ( system. out. println ("Hi" ) ; ) ) public class SubClass extends Example ( ) Клас SubClass автоматично успадковує метод sayHi () визначений у батьківському класі. У той же час, конструктор Example() батьківського класу не успадковується його нащадком SubClass.

Ключове слово this у конструкторах

Конструктори використовують це, щоб послатися на інший конструктор в цьому ж класі, але з іншим списком параметрів. Якщо конструктор використовує ключове слово this , воно має бути в першому рядку, ігнорування цього правила приведе до помилки компілятора. Наприклад: Файл ThisDemo.java public class ThisDemo ( String name; ThisDemo (String s) ( name = s; System. out. println (name) ; ) ThisDemo () ( this ("John" ) ; ) public static void main ( String args ) ( ThisDemo td1 = новий ThisDemo ( " Mary " ) ; ThisDemo td2 = новий ThisDemo () ; ) ) Результат виведення програми: Mary John У цьому прикладі є два конструктори. Перший отримує рядок-аргумент. Другий не отримує жодних аргументів, він просто викликає перший конструктор використовуючи ім'я "John" за замовчуванням. Таким чином, можна за допомогою конструкторів ініціалізувати значення полів явно і за замовчуванням, що часто потрібні в програмах.

Ключове слово super у конструкторах

Конструктори використовують super, щоб викликати конструктор суперкласу. Якщо конструктор використовує super , цей виклик повинен бути у першому рядку, інакше компілятор видасть помилку. Нижче наведено приклад: Файл SuperClassDemo.java public class SuperClassDemo ( SuperClassDemo () ( ) ) class Child extends SuperClassDemo ( Child () ( super () ; ) ) У цьому простому прикладі конструктор Child() містить виклик super() , який створює екземпляр класу SuperClassDemo, на додаток до класу Child. Оскільки super повинен бути першим оператором, що виконується в конструкторі підкласу, цей порядок завжди однаковий і не залежить від того, чи super() використовується. Якщо він не використовується, то спочатку буде виконано за замовчуванням конструктор (без параметрів) кожного суперкласу, починаючи з базового класу. Наступна програма демонструє коли виконуються конструктори. Файл Call.java //Створити суперклас A class A ( A ( ) ( System. out. println ( " Inside A constructor . " ) ; ) ) //Створити підклас B, що розширює клас A class B extends A (B() (System. out. println ("Inside B constructor.");)) //Створити клас (C), що розширює клас class C extends B ( C ( ) ( System. out. println ( " Inside C constructor . " ) ; ) ) class Call ( public static void main ( String args ) ( C c = new C ( ) ; ) ) Висновок цієї програми: Inside A constructor. Inside B constructor. Inside C constructor. Конструктори викликаються порядку підпорядкованості класів. У цьому є певний сенс. Оскільки суперклас не має жодного знання про якийсь підклас, то будь-яка ініціалізація, яку йому потрібно виконати, є окремою. По можливості вона повинна передувати будь-якій ініціалізації, яка виконується підкласом. Тому вона і повинна виконуватися першою.

Конструктори, що настроюються

Механізм ідентифікації типу під час виконання є одним із потужних базових принципів мови Java, що реалізує поліморфізм. Однак такий механізм не страхує розробника від несумісного приведення типів у ряді випадків. Найчастіший випадок – маніпулювання групою об'єктів, різні типи яких заздалегідь невідомі та визначаються під час виконання. Оскільки помилки, пов'язані з несумісністю типів можуть виявитися лише з етапі виконання, це ускладнює їх пошук і ліквідацію. Введення типів, що настроюються в Java 2 5.0 частково відсуває виникнення подібних помилок з етапу виконання на етап компіляції і забезпечує недостатню типову безпеку. Відпадає потреба у явному приведенні типів під час переходу від типу Object до конкретного типу. Слід мати на увазі, що засоби налаштування типів працюють тільки з об'єктами і не поширюються на примітивні типи даних, що лежать поза деревом спадкування класів. Завдяки типам, що настроюються, всі приведення виконуються автоматично і приховано. Це дозволяє убезпечити від невідповідності типів і набагато частіше використовувати код повторно. Типи, що настроюються, можна використовувати в конструкторах. Конструктори можуть бути настроюваними, навіть якщо їх клас не є типом, що настроюється. Наприклад: class GenConstructor (private double val;< T extends Number >GenConstructor (T arg) ( val = arg. doubleValue () ; ) void printValue () ( System. out. println ("val: " + val) ; ) ) class = new GenConstructor (100 ) ;GenConstructor gc2 = new GenConstructor (123.5F ) ;gc1.printValue() ;gc2.printValue() ; викликати з будь-якої
1. Поняття конструктора за умовчанням

Конструктор за замовчуванням – це конструктор, який не має параметрів. Конструктор за замовчуванням може оголошуватись у класі явним чином або генеруватися автоматично.

У найбільш загальному випадку, для класу ClassName, конструктор за замовчуванням має такий вигляд:

class ClassName (... // оголошення конструктора ClassName() ( // Тіло конструктора // ... } ... }
2. У яких випадках конструктор за замовчуванням генерується в класі автоматично, а в яких ні? Приклад

Якщо в класі не оголосити жодного конструктора, то генеруватиметься конструктор за замовчуванням. Тобто, конструктор за замовчуванням генерується у класі автоматично лише у тому випадку, якщо клас не містить реалізації інших конструкторів. Якщо клас містить реалізацію хоча б одного конструктора з параметрами, то щоб оголосити конструктор за замовчуванням, його потрібно оголошувати в класі явним чином.

Наприклад.У наступному оголошенні класу конструктор за замовчуванням генерується автоматично

class CMyClass ( int d; int GetD() ( return d; ) void SetD( int nd) (d = nd;))

Наведений вище код означає, що можна оголошувати об'єкт класу з використанням конструктора за замовчуванням:

// працює, так як у класі більше не реалізовано жодного конструктора CMyClass mc = new CMyClass();

Якщо до тіла CMyClass додати хоча б один інший конструктор (наприклад, конструктор з одним параметром), то конструктор за замовчуванням автоматично генеруватися не буде

class CMyClass ( int d; // конструктор за замовчуванням не генерується автоматично CMyClass( int nd) (d = nd;) int GetD() ( return d; ) void Set( int nd) (d = nd;))

Після наведеної вище реалізації оголосити об'єкт з використанням конструктора за замовчуванням не вдасться. Проте, можна оголосити об'єкт із використанням конструктора з одним параметром

// помилка компіляції, оскільки у класі вже оголошено інший конструктор // CMyClass mc = New CMyClass(); CMyClass mc2 = new CMyClass(7); // а цей код працює

В результаті виконання вищенаведеного рядка буде видано помилку компіляції:

The constructor CMyClass() is undefined

Щоб мати реалізацію конструктора за умовчанням і оголошувати об'єкт класу з використанням конструктора за замовчуванням, його потрібно ставити явно. Це може бути, наприклад, так

class CMyClass ( int d; // явне оголошення конструктора за замовчуванням CMyClass() ( d = 0; ) // оголошення конструктора з 1 параметром, CMyClass( int nd) (d = nd;) int GetD() ( return d; ) void Set( int nd) (d = nd;))

Після такої реалізації можна створювати екземпляр класу з використанням двох конструкторів, наприклад

CMyClass mc = new CMyClass(); // викликається конструктор за замовчуванням mc.d = 25; CMyClass mc2 = new CMyClass(5); // Викликається конструктор з 1 параметром

3. Виклик конструкторів із інших конструкторів. Приклад

Мова програмування Java дозволяє здійснювати виклик конструкторів класу з іншого конструктора цього класу. Для цього використовується ключове слово this, яке є посиланням на поточний клас.

приклад.У прикладі демонструється використання класу CPixel, який реалізує піксел на екрані монітора.

// Клас, який реалізує піксел на екрані монітора public class CPixel ( // внутрішні змінні класу private int x, y; // координати пікселу private int color; // колір піксела // конструктор без параметрів (за замовчуванням конструктор) CPixel() ( x = y = color = 0; ) // конструктор з 2 параметрами, які ініціалізують лише координати CPixel( int _x, int _y) ( x = _x; y = _y; color = 0; ) // конструктор з 1 параметром, який ініціалізує лише колір CPixel( int _color) ( color = _color; x = y = 0; ) // конструктор із 3 параметрами, який викликає конструктор із 2 параметрами CPixel ( int _x, int _y, int _color) ( // Виклик конструктора з 2 параметрами: обов'язково перша операція і лише один раз this(_x, _y); //this(_color); // Повторний виклик конструктора заборонено this.color = _color; // так можна ) // методи доступу int GetX() ( return x; ) int GetY() ( return y; ) int GetColor() ( return color; )

Використання класу CPixel в іншому програмному коді (методі)

CPixel cp1 = new CPixel(2,8); // Виклик конструктора з 2 параметрами CPixel cp2 = new CPixel(3,5,8); // Виклик конструктора, який викличе інший конструктор int d; d = cp1.GetX(); // d = 2 d = cp2. GetColor (); // d = 8 d = cp2. GetY (); // d = 5...

4. Які обмеження (вимоги) накладаються на виклик інших конструкторів із конструктора класу?

Щоб коректно викликати інші конструктори з конструктора класу, потрібно дотримуватись таких вимог (обмежень):

  • викликати можна лише один інший конструктор класу. Викликати двох і більше інших конструкторів цього класу заборонено. Це випливає з логіки, що конструктор класу призначений для створення об'єкта класу лише один раз (а не два і більше разів);
  • виклик іншого конструктора повинен бути першою операцією в конструкторі, що викликає. Якщо у конструкторі виклик іншого конструктора реалізувати другий (третій і т.д.) операцією, то компілятор видасть помилку.

Найважливішою функцією у будь-якому класі є конструктор. Він дозволяє створювати екземпляр об'єкта. Якщо у вас немає конструктора, то створюється конструктор за замовчуванням:

Public class User (
int age;//поле
String firstName;//поле
String lastName;//поле
User() (//ось так виглядає конструктор за замовчуванням
//порожньо
}
}

Як ви могли помітити конструктор теж має ім'я, що і назва класу.
Конструктори, як і функції, можуть приймати на вхід деякий набір параметрів, які вони надалі використовують при створенні об'єкта.

Public class User (
int age;//поле
String firstName;//поле
String lastName;//поле
public User(int age, String firstName, String lastName) (//конструктор з трьома параметрами
this.age = age;
this.firstName = firstName;
this.lastName = lastName;
}
}

Очевидно, що конструктори викликаються в момент створення об'єкта:

User user = new User(18, "Bendjamin", "Button");

Таким чином, ми створили об'єкт класу User, поле Age, якого містить значення 18, firstName Bendjamin, а lastName Button.
Використання даного конструктора набагато зручніше, ніж якби ми намагалися зробити це вручну:

User user=new User();
user.age = 18;
user.firstName = "Bendjamin";
user.lastName = "Button";

Крім цього, якщо ви використовуєте якісь конструктори, то конструктор за замовчуванням не створюється. Таким чином, якщо у нас є тільки конструктор від трьох параметрів, то ми не можемо створити об'єкт даного класу не викликавши його:

User user = new User();//помилка, конструктор за замовчуванням відсутня

Перейдемо до деяких плюшок intellij idea. Натисніть alt+insert:

Це меню автоматичного створення деяких корисних речей для класу. Нас тут зараз цікавить пункт Constructor. Тепер якщо у вас у класі є поля, то можна вибрати від яких полів потрібно створити конструктор і середовище програмування за вас напише його код. Якщо вам потрібен ще один конструктор, то знову натисніть заповітні кнопочки та додайте ще один:

Public class User (
int age;//поле
String firstName;//поле
String lastName;//поле
Public User(int age, String firstName, String lastName) (
this.age = age;
this.firstName = firstName;
this.lastName = lastName;
}

Public User(int age) (
this.age = age;
}
}

Тепер розглянемо дивний рядок this. Назва Змінної = назва Змінної. Ключове слово цього показує, що необхідно поточному екземпляру класу надати значення, передане в конструктор. Таким чином, якщо ми писали б поза класом, то user.age = age, де age це звичайна змінна.
Усередині конструкторів можна викликати інші конструктори, наприклад:

Public class User (
int age;//поле
String firstName;//поле
String lastName;//поле

Public User(int age, String firstName, String lastName) (
this.age = age;
this.firstName = firstName;
this.lastName = lastName;
}

Public User(int age) (
this(age,"unknown", "unknown");//викликаю конструктор від трьох параметрів
}
}

Крім того, якщо у вашому класі використовувалося успадкування, то для того, щоб викликати конструктор батька, необхідно застосовувати ключове слово super
Конструктори потрібні для початкового налаштування об'єкта, якщо необхідно зробити якісь дії з полями, наприклад проініціалізувати їх.

© 2022 androidas.ru - Все про Android