Учебное пособие: Интерфейсы, обратные вызовы, внутренние классы

· NestedClasses.class - класссметодомmain ().

Компилятор разложил матрешки и, как всегда, создал отдельные файлы для каждого класса. При этом, поскольку в идентификаторах недопустимы точки, компилятор заменил их знаками доллара. Для безымянного класса компилятор придумал имя. Локальный класс компилятор пометил номером.

Оказывается, вложенные классы существуют только на уровне исходного кода. Виртуальная машина Java ничего не знает о вложенных классах. Она работает с обычными внешними классами. Для взаимодействия объектов вложенных классов компилятор вставляет в них специальные закрытые поля. Поэтому в локальных классах можно использовать только константы объемлющего метода, т. е. переменные, помеченные словом final. Виртуальная машина просто не догадается передавать изменяющиеся значения переменных в локальный класс. Таким образом, не имеет смысла помечать вложенные классы private, все равно они выходят на самый внешний уровень.

Все эти вопросы можно не брать в голову. Вложенные классы в Java используются только в самом простом виде, главным образом, при обработке событий, возникающих при действиях с мышью и клавиатурой.

В каких же случаях создавать вложенные классы? В теории ООП вопрос о создании вложенных классов решается при рассмотрении отношений "быть частью" и "являться".

Отношения "быть частью" и "являться"

Теперь у нас появились две различные иерархии классов. Одну иерархию образует наследование классов, другую — вложенность классов.

Определив, какие классы будут написаны в вашей программе, и сколько их будет, подумайте, как спроектировать взаимодействие классов? Вырастить пышное генеалогическое дерево классов-наследников или расписать матрешку вложенных классов?

Теория ООП советует прежде всего выяснить, в каком отношении находятся ваши классы P и Q — в отношении "класс Q является экземпляром класса P" ("a class Q is a class р") или в отношении "класс Q — часть класса P" ("a class Q has a class P").

Например: "Собака является животным" или "Собака — часть животного"? Ясно, что верно первое отношение "is-a", поэтому мы и определили класс Dog как расширение класса Pet.

Отношение "is-a" — это отношение "обобщение-детализация", отношение большей или меньшей абстракции, и ему соответствует наследование классов.

Отношение "has-a" — это отношение "целое-часть", ему соответствует вложение.


Приложение 3. Интерфейсы и обратные вызовы

Обратный вызов (callback) широко распространен в программировании. При обратном вызове программист задает действия, которые должны выполняться всякий раз, когда происходит некоторое событие. Например, можно задать действие, которое должно быть выполнено, если будет нажата конкретная кнопка или выбран определенный пункт меню.

Рассмотрим простую ситуацию. Пакет java.swing содержит класс Timer , который можно использовать для отсчета интервалов времени. Например, если в программе предусмотрены часы, то с помощью класса Timer, можно отсчитывать каждую секунду и обновлять циферблат часов. Устанавливая таймер, мы задаем интервал времени и указываем, что должно произойти по его истечении.

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

Классы из стандартной библиотеки языка Java используют объектно-ориентированный подход. Программист должен передать таймеру объект некоторого класса. После этого таймер вызывает один из методов данного объекта.

Передача объекта – более гибкий механизм, чем вызов функций, поскольку объект может нести с собой дополнительную информацию. Значит, таймер должен знать, какой метод он должен вызвать. Для этого таймеру нужно указать объект класса, реализующего интерфейс ActionListener из пакета java . awt . event .

Воткаквыглядитэтотинтерфейс

public interface ActionListener

{

void actionPerformed (ActionEvent event);

}

По истечении заданного интервала времени таймер вызывает метод actionPerformed .

Рассмотрим пример. Пусть нужно каждые 10 секунд выводить на экран сообщение «Текущее время », сопровождаемое звуковым сигналом. Для этого необходимо определить класс, реализующий интерфейс ActionListener. Затем поместить операторы, которые нужно выполнить, внутрь методаactionPerformed.

class Timerprinter implements ActionListener

{

public voidactionPerformed(ActionEvent event)

{

К-во Просмотров: 500
Бесплатно скачать Учебное пособие: Интерфейсы, обратные вызовы, внутренние классы