Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование на Java.docx
Скачиваний:
2
Добавлен:
01.05.2025
Размер:
3.45 Mб
Скачать

3.18.2 Вложенные (nested) классы

Если не существует необходимости в связи объекта внутреннего класса с объектом внешнего класса, то есть смысл сделать такой класс статическим.

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

При объявлении такого внутреннего класса присутствует служебное слово static, и такой класс называется вложенным (nested). Если класс вложен в интерфейс, то он становится статическим по умолчанию. Такой класс способен наследовать другие классы, реализовывать интерфейсы и являться объектом наследования для любого класса, обладающего необходимыми правами доступа. В то же время статический вложенный класс для доступа к нестатическим членам и методам внешнего класса должен создавать объект внешнего класса, а напрямую имеет доступ только к статическим полям и методам внешнего класса. Для создания объекта вложенного класса объект внешнего класса создавать нет необходимости. Подкласс вложенного класса не способен унаследовать возможность доступа к членам внешнего класса, которыми наделен его суперкласс.

Листинг 3.31

public class Ship {

private int id;

// abstract, final, private, protected - допустимы

public static class LifeBoat {

public static void down() {

System.out.println("шлюпки на воду!");

}

public void swim() {

System.out.println("отплытие шлюпки");

}

}

}

public class Main {

public static void main(String[] args) {

// вызов статического метода

Ship.LifeBoat.down();

// создание объекта статического класса

Ship.LifeBoat lf = new Ship.LifeBoat();

// вызов обычного метода

lf.swim();

}

}

Статический метод вложенного класса вызывается при указании полного относительного пути к нему. Объект lf вложенного класса создается с использованием имени внешнего класса без вызова его конструктора.

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

3.18.3 Анонимные (anonymous) классы

Анонимные (безымянные) классы применяются для придания уникальной функциональности отдельно взятому объекту для обработки событий, реализации блоков прослушивания и т.д. Можно объявить анонимный класс, который будет расширять другой класс или реализовывать интерфейс при объявлении одного, единственного объекта, когда остальным объектам этого класса будет соответствовать реализация метода, определенная в самом классе. Объявление анонимного класса выполняется одновременно с созданием его объекта посредством оператора new.

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

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

Листинг 3.32

public class TypeQuest {

private int id = 1;

public TypeQuest() {

}

public TypeQuest(int id) {

this.id = id;

}

public void addNewType() {

// реализация

System.out.println("добавлен вопрос на соответствие");

}

}

public class Main {

public static void main(String[] args) {

TypeQuest unique = new TypeQuest() {// анонимный класс #1

public void addNewType() {

// новая реализация метода

System.out.println("добавлен вопрос со свободным ответом");

}

};// конец объявления анонимного класса

unique.addNewType();

new TypeQuest(71) {// анонимный класс #2

private String name = "Drag&Drop";

public void addNewType() {

// новая реализация метода #2

System.out.println("добавлен " + getName());

}

String getName() {

return name;

}

}.addNewType();

TypeQuest standard = new TypeQuest(35);

standard.addNewType();

}

}

В результате будет выведено:

добавлен вопрос со свободным ответом

добавлен Drag&Drop

добавлен вопрос на соответствие

При запуске приложения происходит объявление объекта unique c применением анонимного класса, в котором переопределяется метод addNewType(). Вызов данного метода на объекте unique приводит к вызову версии метода из анонимного класса, который компилируется в объектный модуль с именем RunnerAnonym$1.

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

При помощи анонимных классов удобно реализовувать интерфейс. Пример реализации методов интерфейса приведен в листинге 3.33.

Листинг 3.33

// интерфейс OnOff

public interface OnOff {

public void on();

public void off();

}

public class Main {

public static void main(String[] args) {

// реализация методдов для объекта radio

OnOff radio =new OnOff() {

@Override

public void on() {

System.out.println("Радио включено");

}

@Override

public void off() {

System.out.println("Радио выключено");

}

};

// реализация методдов для объекта tv

OnOff tv =new OnOff() {

@Override

public void on() {

System.out.println("Телевизор включен");

}

@Override

public void off() {

System.out.println("Телевизор выключен");

}

};

radio.on();

radio.off();

tv.on();

tv.off();

}

}

В результате рабботы программы получим:

Радио включено

Радио выключено

Телевизор включен

Телевизор выключен

Выводы к главе:

  • Наследование – один из трех базовых принципов объектно-ориентированного программирования.

  • В Java нет множественного наследования классов.

  • С помощью наследования можно сформировать общий класс, определяющий характерные особенности некоторого понятия.

  • В языке Java наследуемый класс принято называть суперклассом. Его дочерние классы называются подклассами.

  • Подкласс – это специализированная версия суперкласса. Он наследует все переменные и методы, определенные в суперклассе, и дополняет их своими элементами.

  • Абстрактный метод – метод имеющий заголовок, но не имеющий реализации(тела).

  • Если в классе есть хотя бы один абстрактный метод, то класс становится абстрактным.

  • Интерфейс не содержит реализации ни одного метода. Он описывает, что должно быть сделано, но не поясняет, как.

  • Если интерфейс определен, его можно реализовать в сколь угодно большом количестве классов.

  • Один класс может реализовать любое количество интерфейсов.

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

  • Пакет – это контейнер, позволяющий разделить пространство имен классов.

  • В разных пакетах могут быть классы с одинаковыми именами, в одном – нет.

  • Классы могут взаимодействовать друг с другом не только посредством наследования и использования ссылок, но и посредством организации логической структуры с определением одного класса в теле другого.

  • Статический класс описанный в теле другого класса – вложенный.

  • Нестатические вложенные классы принято называть внутренними (inner) классами.

  • Анонимный класс расширяет другой класс или реализует интерфейс при объявлении одного, единственного объекта, когда остальным объектам этого класса будет соответствовать реализация методов, определенная в самом классе. Объявление анонимного класса выполняется одновременно с созданием его объекта посредством оператора new.

Задания к главе:

1). Разработать интерфейс Арифметика. Методы – сложение, сравнение. Класс Матрица (поле – двумерный массив) реализует интерфейс. Дополнительные методы:

создание матрицы (размерность и значения вводятся с консоли),

заполенение матрицы случайными числами,

вывод 1 значения из матрицы, по номеру ячейки,

масштабирование матрицы в меньшую сторону (поэлементное деление на число).

Класс Строки (поле – массив символов char) реализует интерфейс. Дополнительные методы:

создание строки (ввод с консоли),

вывод 1 значение из строки, по номеру.

Класс Вектор (как набор значений, поле – одномерный массив) реализует интерфейс. Дополнительные методы:

создание вектора (ввод с консоли),

сравнение длин двух векторов.

2). Создать интерфейс с методом площадь и реализовать его в классах: прямоугольник, круг, прямоугольный треугольник, трапеция со своими.

Для проверки определить массив ссылок на интерфейс, которым присваиваются различные объекты.

Площадь трапеции:S=(a+b)h/2

3). Создать интерфейс с методом норма и реализовать его в классах: комплексные числа, вектор из 10 элементов, матрица (2х2). Определить метод нормы:

для комплексных чисел – модуль в квадрате,

для вектора – корень квадратный из суммы элементов по модулю,

для матрицы – максимальное значение по модулю.

4). Реализовать интерфейсы, а также наследование и полиморфизм для следующих классов:

4.1). interface Абитуриент <- abstract class Студент <- class Студент-Заочник.

4.2). interface Сотрудник <- class Инженер <-class Руководитель.

4.3). interface Здание <- abstract class Общественное Здание <- class Театр.

4.4). interface Корабль <- abstract class Военный Корабль <- class Авианосец.

4.5). interface Корабль <- class Грузовой Корабль <- class Танкер.

4.6). interface Техника <- abstract class Плеер <- class Видеоплеер.

4.7). interface Транспортное Средство <- abstract class Общественный Транспорт <- class Трамвай.