Цепочка конструкторов
Часть раздела Объектно-ориентированное программирование путешествия по Java на Coddy — урок 23 из 87.
Цепочка конструкторов — это процесс вызова одного конструктора из другого. Этот метод помогает избежать дублирования кода, когда класс имеет несколько конструкторов или при работе с иерархиями наследования.
Внутри одного и того же класса вы можете объединять конструкторы в цепочку, используя this(). Это позволяет вам иметь один «основной» конструктор, который выполняет всю работу, в то время как другие конструкторы просто делегируют полномочия ему:
public class Rectangle {
private int width;
private int height;
public Rectangle() {
this(1, 1); // Вызывает конструктор с двумя параметрами
}
public Rectangle(int size) {
this(size, size); // Создает квадрат
}
public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
}При наследовании цепочка вызовов конструкторов происходит автоматически. Когда вы создаете объект подкласса, Java сначала вызывает конструктор родительского класса с помощью super(). Если вы не вызываете super() явно, Java автоматически вставляет super() (версию без аргументов):
public class Animal {
private String name;
public Animal(String name) {
this.name = name;
System.out.println("Animal constructor");
}
}
public class Dog extends Animal {
private String breed;
public Dog(String name, String breed) {
super(name); // Должно быть первой строкой
this.breed = breed;
System.out.println("Dog constructor");
}
}Создание new Dog("Buddy", "Labrador") сначала выводит "Animal constructor", а затем "Dog constructor". Это гарантирует, что родительские классы всегда инициализируются должным образом до того, как дочерний класс добавит свои собственные настройки.
Задание
ЛегкоДавайте создадим систему заказа товаров, которая демонстрирует цепочку конструкторов как внутри класса, так и в иерархии наследования. Вы увидите, как this() связывает конструкторы в одном и том же классе, а super() связывает их с конструкторами родительского класса.
Вы создадите три файла для организации вашего кода:
Product.java: Создайте родительский класс, представляющий любой товар в магазине. Он должен иметь:- Приватные поля для
name(String) иprice(double) - Основной конструктор, который принимает и имя, и цену, инициализирует поля и выводит:
Product constructor: [name] - Второй конструктор, который принимает только имя и вызывает основной конструктор с помощью
this(name, 0.0)для установки цены по умолчанию 0.0 - Методы
getName()иgetPrice()для доступа к полям
- Приватные поля для
Electronics.java: Создайте подкласс, который расширяет Product и добавляет информацию о гарантии:- Приватное поле для
warrantyYears(int) - Основной конструктор, который принимает name, price и warrantyYears — используйте
super(name, price)для инициализации родительского класса, затем установите гарантию и выведите:Electronics constructor: [warrantyYears] year warranty - Второй конструктор, который принимает только name и price, вызывая основной конструктор с помощью
this(name, price, 1)для предоставления стандартной гарантии на 1 год - Третий конструктор, который принимает только имя, вызывая второй конструктор с помощью
this(name, 0.0) - Метод
getDetails(), который возвращает:[name] - $[price] ([warrantyYears] year warranty)
- Приватное поле для
Main.java: Продемонстрируйте работу цепочки конструкторов. Вы получите три входных значения: название товара (String), цену (double) и количество лет гарантии (int). Создайте объект Electronics, используя все три параметра, затем выведите результат методаgetDetails().
Вы получите три входных значения: название товара, цену и количество лет гарантии.
Отформатируйте цену в getDetails() так, чтобы она отображала 2 знака после запятой, используя String.format("%.2f", price). Внимательно следите за выводом — вы увидите сообщения конструкторов, появляющиеся по порядку, что показывает, как цепочка переходит от родителя к потомку!
Шпаргалка
Цепочка конструкторов — это процесс вызова одного конструктора из другого для предотвращения дублирования кода.
Цепочка вызовов внутри одного класса
Используйте this() для вызова другого конструктора в том же классе:
public class Rectangle {
private int width;
private int height;
public Rectangle() {
this(1, 1); // Вызывает конструктор с двумя параметрами
}
public Rectangle(int size) {
this(size, size); // Создает квадрат
}
public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
}Цепочка вызовов при наследовании
Используйте super() для вызова конструктора родительского класса. Это должна быть первая строка в конструкторе:
public class Animal {
private String name;
public Animal(String name) {
this.name = name;
System.out.println("Animal constructor");
}
}
public class Dog extends Animal {
private String breed;
public Dog(String name, String breed) {
super(name); // Должно быть первой строкой
this.breed = breed;
System.out.println("Dog constructor");
}
}Если вы не вызываете super() явно, Java автоматически вставляет super() (версию без аргументов). Конструкторы родительского класса всегда вызываются перед конструкторами дочернего класса, что обеспечивает правильный порядок инициализации.
Попробуйте сами
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Считать входные данные
String name = scanner.nextLine();
double price = scanner.nextDouble();
int warrantyYears = scanner.nextInt();
// TODO: Создайте объект Electronics, используя все три параметра
// TODO: Выведите результат getDetails()
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово thisМетодыПоля (атрибуты)Метод-конструкторПерегрузка конструкторовИтоги — Простой калькулятор4Наследование
Основы наследования (extends)Ключевое слово superПереопределение методов (@Override)Цепочка конструкторовКласс ObjectОдиночное и многоуровневое наследованиеПочему нет множественного наследования классовИтоги — Иерархия сотрудников7Специальные методы и класс Object
Метод toString()equals() и hashCode()Метод clone()compareTo() и ComparableИнтерфейс ComparatorПовторение — Кастомная сортировка2Модификаторы доступа и инкапсуляция
Обзор уровней доступаМетоды геттеры и сеттерыСокрытие данныхКлючевое слово finalИтоги — Менеджер банковского счета5Полиморфизм
Основы перегрузки методовПереопределение методов (Run-Time)Upcasting и DowncastingОператор instanceofАбстрактные классы и методыИтоги: Калькулятор фигур8Продвинутые концепции ООП
Композиция против наследованияАгрегация против композицииВнутренние, вложенные и анонимные классыEnums и методы перечисленийRecords (Java 16+)Sealed-классы (Java 17+)11Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн BuilderПаттерн ObserverПаттерн Strategy3Свойства класса и статические члены
Переменные экземпляра и статические переменныеСтатические методыСтатические блокиКонстанты (static final)Итоги: Счетчик и утилиты6Интерфейсы и абстрактные классы
Введение в интерфейсыРеализация интерфейсовРеализация нескольких интерфейсовDefault и Static методы в интерфейсахАбстрактные классы vs ИнтерфейсыФункциональные интерфейсыИтоги — Платежная система9Обобщения
Введение в обобщенияОбобщенные классыОбобщенные методыОграниченные параметры типаСимволы подстановки (Wildcards: ?, extends, super)Итоги — Обобщенный контейнер12Паттерны проектирования. Часть 2
Паттерн «Команда»Паттерн «Адаптер»Паттерн «Декоратор»Паттерн «Шаблонный метод»Паттерн «Состояние»Паттерн «Компоновщик»Паттерн «Итератор»