Skip to main content

03. Конструкторы

Теория

Всегда во время создания объекта вызывается его конструктор. Если ни один конструктор в классе не определён, тогда вызывается конструктор по умолчанию:

    // конструктор по умолчанию
Worker() {
}

Если он не задан явно в теле класса, тогда компилятор добавит его автоматически при сборке.

Всё, что мы напишем в теле конструктора по умолчанию, будет выполняться при каждом создании объекта

Добавим в класс сотрудника Worker из прошлой главый конструктор по умолчанию:

    // конструктор по умолчанию
Worker() {
System.out.println("Вызван конструктор сотрудника по умолчанию");
}

Чтобы объявить конструктор, нужно просто написать название класса, затем круглые скобки (), как у обычных методов, затем - тело конструктора.

Теперь перепишем main():

package com.company;

public class Main {

public static void main(String[] args) {
Worker worker = new Worker();
}
}

Запустим программу, на консоль будет выведено:

Вызван конструктор сотрудника по умолчанию

Если теперь мы добавим создание второго объекта:

package com.company;

public class Main {

public static void main(String[] args) {
Worker worker = new Worker();
Worker worker2 = new Worker();
}
}

то на консоль выведется две строки:

Вызван конструктор сотрудника по умолчанию
Вызван конструктор сотрудника по умолчанию

Т.к. конструктор - это метод, то можно добавить в него параметры:

    // конструктор от возраста
Worker(int age) {
this.age = age;
System.out.println("Конструктор сотрудника от возраста");
}

// конструктор от имени и возраста
Worker(int age, String name) {
this.age = age;
this.name = name;
System.out.println("Конструктор сотрудника от имени и возраста");
}
Обратите внимание

В новых конструкторах используется ключевое слово this. Т.к. названия параметров конструктора совпадают с названиями полей, то чтобы обратиться к полю, нужно использовать конструкцию this.имя_поля, а чтобы к параметру конструктора - просто имя_поля.

Перепишем теперь метод main()

package com.company;

public class Main {

public static void main(String[] args) {
Worker worker = new Worker();
Worker worker2 = new Worker(25);
Worker worker3 = new Worker(30, "Павлов Сергей");
}
}

На консоль будет выведено:

Конструктор сотрудника по умолчанию
Конструктор сотрудника от возраста
Конструктор сотрудника от имени и возраста

Теперь можно разобраться, как работает команда создания сканера:

Scanner sc = new Scanner(System.in)

Она создаёт объект класса сканера, при этом в конструктор передаётся объект потока данных, введённых в консоль.

Перегрузка методов

Если конструктор - это тоже метод, то не помешает ли это компиляции наших исходников? Как java понимает, какой метод загружать?

Если у класса два метода с одинаковыми названиями, такой подход называется перегрузкой методов. Java определяет, какой именно метод вызвать по переданным аргументам. Если мы не передали ни одного аргумента, вызывается конструктор по умолчанию, если один целочисленный, то java ищет конструктор с одним целочисленным параметром и т.д.

Весь код

package com.company;

import java.util.Random;

public class Worker {
// фамилия и имя
String name;
// возраст
int age;
// стаж
int exp;
// продуктивность
double kpi;

// конструктор по умолчанию
Worker() {
System.out.println("Конструктор сотрудника по умолчанию");
}

// конструктор от возраста
Worker(int age) {
this.age = age;
System.out.println("Конструктор сотрудника от возраста");
}

// конструктор от имени и возраста
Worker(int age, String name) {
this.age = age;
this.name = name;
System.out.println("Конструктор сотрудника от имени и возраста");
}

// увеличить возраст на 1
void incAge() {
age++;
}

// изменить стаж
void changeExp(int d) {
exp += d;
}

// отработал ли сотрудник больше пяти лет
boolean isOldTimer() {
return exp > 5;
}

// исполнилось ли сотруднику 30 лет
boolean isUp30() {
return age >= 30;
}

// предложение от сотрудника
Worker offer() {
// создаём нового сотрудника
Worker worker = new Worker();
// имя сотрудника получается из соединения первого
// элемента разбиения строки по пробелу и строки " Рекомендация"
worker.name = name.split(" ")[0] + " Рекомендация";
// опыта пока что нет
worker.exp = 0;

// создаём генератор случайных чисел
Random random = new Random();
// возраст работника - случайное число от 25 до 60
worker.age = random.nextInt() % (60 - 25) + 26;
return worker;
}

// задать стаж
void setExp(int exp) {
this.exp = exp;
}

// получить стаж
int getExp() {
return exp;
}

// строковое представление
@Override
public String toString() {
return "Worker{" + name + ": " + exp + "/" + String.format("%.2f", kpi) + "}";
}

// проверка на равенство
boolean equals(Worker worker) {
if (age != worker.age)
return false;
if (exp != worker.exp)
return false;
// встроенное сравнивание вещественных чисел
if (Double.compare(worker.kpi, kpi) != 0)
return false;
// встроенное сравнивание строк
return name.equals(worker.name);
}
}

Задание

В качестве задания вам необходимо написать требуемые классы либо решить задачу с их использованием. Система совмещает ваш код со своим и запускает тестирование.

Прочитайте внимательно, что именно нужно отправить в тот или иной тест.

Часть вывода в консоль система выполняет за вас. Вам нужно выводить только то, что требуется в задании.

xor

Ссылка на контест