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

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

Жанры

Философия Java3

Эккель Брюс

Шрифт:

}

} /* Output-Конструктор Game Конструктор BoardGame Конструктор Chess *///:-

Если не вызвать конструктор базового класса в BoardGame, то компилятор «пожалуется» на то, что не может обнаружить конструктор в форме Game. Вдобавок вызов конструктора базового класса должен быть первой командой в конструкторе производного класса. (Если вы вдруг забудете об этом, компилятор вам тут же напомнит.)

Делегирование

Третий вид отношений, не поддерживаемый в Java напрямую, называется делегированием. Он занимает промежуточное положение

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

//. reusing/SpaceShipControls.java

public class SpaceShipControls { void up(int velocity) {} void down(int velocity) {} void left(int velocity) {} void right(int velocity) {} void forward(int velocity) {} void back(int velocity) {} void turboBoostO {} } ///-

Для построения космического корабля можно воспользоваться наследованием:

// reusing/SpaceShip java

public class SpaceShip extends S^ceShipControls { private String name.

public SpaceShip(String name) { this.name = name, }

public String toStringO { return name. }__

public static void main(String[] args) {

SpaceShip protector = new SpaceShipC'NSEA Protector"), protector forward(lOO).

}

} /// ~

Однако космический корабль не может рассматриваться как частный случай своего управляющего модуля — несмотря на то, что ему, к примеру, можно приказать двигаться вперед (forward). Точнее сказать, что SpaceShip содержит SpaceShipControls, и в то же время все методы последнего предоставляются классом SpaceShip. Проблема решается при помощи делегирования:

// reusing/SpaceShipDelegation java

public class SpaceShipDelegation { private String name, private SpaceShipControls controls =

new SpaceShipControlsO: public SpaceShipDelegation(String name) {

this name = name. }

// Делегированные методы: public void back(int velocity) { controls.back(velocity);

}

public void down(int velocity) { controls.down(velocity);

}

public void forward(int velocity) { controls forward(velocity).

}

public void leftCint velocity) { controls left(velocity).

}

public void rightOnt velocity) { controls right(velocity);

}

public void turboBoostO {

controls.turboBoostO.

}

public void up(int velocity) { controls.up(velocity):

}

public static void main(String[] args) { SpaceShipDelegation protector =

new SpaceShipDelegationC'NSEA Protector"); продолжение &

protector.forwarcK 100);

}

} ///:-

Как видите, вызовы методов переадресуются встроенному объекту controls, а интерфейс остается таким же, как и при наследовании. С другой стороны, делегирование позволяет лучше управлять происходящим, потому что вы можете ограничиться небольшим подмножеством методов встроенного объекта.

Хотя

делегирование не поддерживается языком Java, его поддержка присутствует во многих средах разработки. Например, приведенный пример был автоматически сгенерирован в JetBrains Idea IDE.

Сочетание композиции и наследования

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

II: reusing/PlaceSetting.java 11 Совмещение композиции и наследования, import static net.mindview.util.Print.*;

class Plate {

'PlateCint i) {

print("Конструктор Plate");

}

}

class DinnerPlate*extends Plate { DinnerPlate(int i) { super(i),

print("Конструктор DinnerPlate");

class Utensil {

Utensil(int i) {

print("Конструктор Utensil");

}

}

class Spoon extends Utensil { Spoon(int i) {

super(i);

print'CKoHCTpyKTop Spoon");

class Fork extends Utensil { Fork(int i) {

super(i);

System.out.println("Конструктор Fork");

}

class Knife extends Utensil { Knife(int i) {

super(i):

print("Конструктор Knife");

class Custom {

Custom(int i) {

print("Конструктор Custom");

public class'PIaceSetting extends Custom { private Spoon sp; private Fork frk; private Knife kn; private DinnerPlate pl; public PIaceSetting(int i) { super(i + 1); sp = new Spoon(i + 2); frk = new Fork(i + 3); kn = new Knifed + 4); pl = new DinnerPlated + 5); pri nt("Конструктор PlaceSetti ng"):

}

public static void main(String[] args) {

. PlaceSetting x = new PlaceSetting(9);

}

} /* Output: Конструктор Custom Конструктор Utensil Конструктор Spoon Конструктор Utensil Конструктор Fork Конструктор Utensil Конструктор Knife Конструктор Plate Конструктор DinnerPlate конструктор PlaceSetting *///:-

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

Обеспечение правильного завершения

В Java отсутствует понятие деструктора из С++ — метода, автоматически вызываемого при уничтожении объекта. В Java программисты просто «забывают» об объектах, не уничтожая их самостоятельно, так как функции очистки памяти возложены на сборщика мусора.

Во многих случаях эта модель работает, но иногда класс выполняет некоторые операции, требующие завершающих действий. Как упоминалось в главе 5, вы не знаете, когда будет вызван сборщик мусора и произойдет ли это вообще. Поэтому, если в классе должны выполняться действия по очистке, вам придется написать для этого особый метод и сделать так, чтобы программисты-клиенты знали о необходимости вызова этого метода. Более того, как описано в главе 10, вам придется предусмотреть возможные исключения и выполнить завершающие действия в секции finally.

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

Эволюция мага

Лисина Александра
2. Гибрид
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Эволюция мага

Искатель 1

Шиленко Сергей
1. Валинор
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Искатель 1

Хозяйственная помощница для идеала

Свободина Виктория
15. Помощница
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Хозяйственная помощница для идеала

Прометей: каменный век II

Рави Ивар
2. Прометей
Фантастика:
альтернативная история
7.40
рейтинг книги
Прометей: каменный век II

Как я строил магическую империю 7

Зубов Константин
7. Как я строил магическую империю
Фантастика:
попаданцы
постапокалипсис
аниме
фантастика: прочее
5.00
рейтинг книги
Как я строил магическую империю 7

Солнечный корт

Сакавич Нора
4. Все ради игры
Фантастика:
зарубежная фантастика
5.00
рейтинг книги
Солнечный корт

Случайная жена для лорда Дракона

Волконская Оксана
Фантастика:
юмористическая фантастика
попаданцы
5.00
рейтинг книги
Случайная жена для лорда Дракона

Часовое имя

Щерба Наталья Васильевна
4. Часодеи
Детские:
детская фантастика
9.56
рейтинг книги
Часовое имя

Возвышение Меркурия. Книга 5

Кронос Александр
5. Меркурий
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 5

Кодекс Крови. Книга IХ

Борзых М.
9. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга IХ

Начальник милиции. Книга 4

Дамиров Рафаэль
4. Начальник милиции
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Начальник милиции. Книга 4

Черный Маг Императора 12

Герда Александр
12. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Черный Маг Императора 12

Дочь опальной герцогини

Лин Айлин
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Дочь опальной герцогини

Маленькая слабость Дракона Андреевича

Рам Янка
1. Танцы на углях
Любовные романы:
современные любовные романы
эро литература
5.25
рейтинг книги
Маленькая слабость Дракона Андреевича