Menu
Coddy logo textTech

Цепочка конструкторов

Часть раздела Объектно-ориентированное программирование путешествия по 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". Это гарантирует, что родительские классы всегда инициализируются должным образом до того, как дочерний класс добавит свои собственные настройки.

challenge icon

Задание

Легко

Давайте создадим систему заказа товаров, которая демонстрирует цепочку конструкторов как внутри класса, так и в иерархии наследования. Вы увидите, как 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()
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование