Чтение онлайн

на главную - закладки

Жанры

Программирование на Java

Вязовик Н.А.

Шрифт:

public class Vector {

private int vx, vy;

protected double length;

public Vector(int x, int y) {

super;

vx=x;

vy=y;

length=Math.sqrt(vx*vx+vy*vy);

}

public Vector(int x1, int y1,

int x2, int y2) {

this(x2-x1, y2-y1);

}

}

Большим достоинством такого метода записи является то, что удалось избежать дублирования идентичного кода. Например, если процесс инициализации объектов этого класса увеличится на один шаг (скажем, добавится проверка длины на равенство нулю), то такое изменение надо будет внести только в первый конструктор. Такой подход помогает избежать случайных ошибок, так как исчезает необходимость тиражировать изменения в нескольких местах.

Разумеется, такое обращение к конструкторам своего класса не должно приводить к зацикливаниям, иначе будет выдана ошибка компиляции. Цепочка this должна в итоге приводить к super, который должен присутствовать (явно или неявно) хотя бы в одном из конструкторов. После того, как отработают конструкторы всех родительских классов, будет продолжено выполнение каждого конструктора, вовлеченного в процесс создания объекта.

public class Test {

public Test {

System.out.println("Test");

}

public Test(int x) {

this;

System.out.println("Test(int x)");

}

}

После выполнения выражения new Test(0) на консоли появится:

Test

Test(int x)

В заключение рассмотрим применение модификаторов доступа для конструкторов. Может вызвать удивление возможность объявлять конструкторы как private. Ведь они нужны для генерации объектов, а к таким конструкторам ни у кого не будет доступа. Однако в ряде случаев модификатор private может быть полезен. Например:

* private -конструктор может содержать инициализирующие действия, а остальные конструкторы будут использовать его с помощью this, причем прямое обращение к этому конструктору по каким-то причинам нежелательно;

* запрет на создание объектов этого класса, например, невозможно создать экземпляр класса Math ;

* реализация специального шаблона проектирования из ООП Singleton, для работы которого требуется контролировать создание объектов, что невозможно в случае наличия не- private конструкторов.

Инициализаторы

Наконец, последней допустимой конструкцией в теле класса является объявление инициализаторов. Записываются объектные инициализаторы очень просто – внутри фигурных скобок.

public class Test {

private int x, y, z;

// инициализатор объекта {

x=3;

if (x>0)

y=4;

z=Math.max(x, y);

}

}

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

Было указано уже три вида инициализирующего кода в классах – конструкторы, инициализаторы переменных, а теперь добавились объектные инициализаторы. Необходимо разобраться, в какой последовательности что выполняется, в том числе при наследовании. При создании экземпляра класса вызванный конструктор выполняется следующим образом:

если первой строкой идет обращение к конструктору родительского класса (явное или добавленное компилятором по умолчанию), то этот конструктор исполняется;

в случае успешного исполнения вызываются все инициализаторы полей и объекта в том порядке, в каком они объявлены в теле класса;

если первой строкой идет обращение к другому конструктору этого же класса, то он вызывается. Повторное выполнение инициализаторов не производится.

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

Во-вторых, теперь можно сформулировать наиболее гибкий подход к инициализации final -полей. Главное требование – чтобы такие поля были проинициализированы ровно один раз. Это можно обеспечить в следующих случаях:

если инициализировать поле при объявлении;

если инициализировать поле только один раз в инициализаторе объекта (он должен быть записан после объявления поля);

если инициализировать поле только один раз в каждом конструкторе, в первой строке которого стоит явное или неявное обращение к конструктору родителя. Конструктор, в первой строке которого стоит this, не может и не должен инициализировать final -поле, так как цепочка this -вызовов приведет к конструктору с super, в котором эта инициализация обязательно присутствует.

Для иллюстрации порядка исполнения инициализирующих конструкций рассмотрим следующий пример:

public class Test {

{

System.out.println("initializer");

}

int x, y=getY;

final int z; {

System.out.println("initializer2");

}

private int getY {

System.out.println("getY "+z);

return z;

}

public Test {

System.out.println("Test");

z=3;

}

public Test(int x) {

this;

System.out.println("Test(int)");

// z=4; - нельзя! final-поле уже

// было инициализировано

}

}

После выполнения выражения new Test на консоли появится:

initializer

getY 0

initializer2

Test

Обратите внимание, что для инициализации поля y вызывается метод getY, который возвращает значение final -поля z, которое еще не было инициализировано. Поэтому в итоге поле y получит значение по умолчанию 0, а затем поле z получит постоянное значение 3, которое никогда уже не изменится.

Поделиться:
Популярные книги

Отмороженный 9.0

Гарцевич Евгений Александрович
9. Отмороженный
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Отмороженный 9.0

Брак по-драконьи

Ардова Алиса
Фантастика:
фэнтези
8.60
рейтинг книги
Брак по-драконьи

Бояръ-Аниме. Газлайтер. Том 33

Володин Григорий Григорьевич
33. История Телепата
Фантастика:
боевая фантастика
попаданцы
аниме
6.25
рейтинг книги
Бояръ-Аниме. Газлайтер. Том 33

На границе империй. Том 7. Часть 2

INDIGO
8. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
6.13
рейтинг книги
На границе империй. Том 7. Часть 2

Сирота

Шмаков Алексей Семенович
1. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
5.00
рейтинг книги
Сирота

Князь Андер Арес 3

Грехов Тимофей
3. Андер Арес
Фантастика:
рпг
аниме
фэнтези
5.00
рейтинг книги
Князь Андер Арес 3

Изгой Проклятого Клана. Том 2

Пламенев Владимир
2. Изгой
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Изгой Проклятого Клана. Том 2

Кадет Морозов

Шелег Дмитрий Витальевич
4. Живой лёд
Фантастика:
боевая фантастика
5.72
рейтинг книги
Кадет Морозов

Эпоха Опустошителя. Том V

Павлов Вел
5. Вечное Ристалище
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Эпоха Опустошителя. Том V

Ермак. Противостояние. Книга одиннадцатая

Валериев Игорь
11. Ермак
Фантастика:
попаданцы
альтернативная история
4.50
рейтинг книги
Ермак. Противостояние. Книга одиннадцатая

Страж Кодекса. Книга II

Романов Илья Николаевич
2. КО: Страж Кодекса
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Страж Кодекса. Книга II

Граф

Ланцов Михаил Алексеевич
6. Помещик
Фантастика:
альтернативная история
5.00
рейтинг книги
Граф

Я еще барон. Книга III

Дрейк Сириус
3. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я еще барон. Книга III

Кодекс Охотника. Книга XXXIX

Сапфир Олег
39. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
боевая фантастика
5.00
рейтинг книги
Кодекс Охотника. Книга XXXIX