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

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

Жанры

Философия Java3

Эккель Брюс

Шрифт:

}

} ///.-

Теперь класс PDestination является частью метода destination, а не частью класса Parcel5. Поэтому доступ к классу PDestination возможен только из метода destination. Обратите внимание на восходящее преобразование, производимое в команде return, — из метода возвращается лишь ссылка на базовый класс Destination, и ничего больше. Конечно, тот факт, что имя класса PDestination находится внутри метода destination, не означает, что объект PDestination после выхода из этого метода станет недоступным.

Идентификатор PDestination может использоваться для внутренних классов каждого отдельного класса в одном подкаталоге, без порождения конфликта имен.

Следующий пример демонстрирует, как можно вложить внутренний класс в произвольную область действия:

//. innerclasses/Parcel6 java

// Вложение класса в область действия

public class Parcel6 {

private void internalTracking(boolean b) { if(b) {

class TrackingSlip {

private String id;

TrackingSlipCString s) { id = s;

}

String getSlipO { return id; }

}

TrackingSlip ts = new TrackingSlipC'ожидание");

String s = ts getSlipO;

}

// Здесь использовать класс нельзя!

// Вне области видимости.

//! TrackingSlip ts = new Tracki ngSlipCx").

}

public void trackO { internalTracking(true), }

public static void main(String[] args) { Parcel6 p = new Parcel60; p trackO;

}

} ///:-

Класс TrackingSlip вложен в область действия команды if. Это не значит, что класс создается в зависимости от условия — он компилируется вместе со всем остальным кодом. Однако при этом он недоступен вне контекста, в котором был определен. В остальном он выглядит точно так же, как и обычный класс.

Безымянные внутренние классы

Следующий пример выглядит немного странно:

// innerclasses/Parcel7 java

// Метод возвращает экземпляр безымянного внутреннего класса

public class Parcel7 {

public Contents contents О {

return new Contents О { // Вставить определение класса private int i = 11; public int valueO { return i; } }. // В данной ситуации точка с запятой необходима

}

public static void main(String[] args) { Parcel7 p = new Parcel7; Contents с = p.contents О;

}

} ///-

Метод contents совмещает создание возвращаемого значения с определением класса, который это возвращаемое значение и представляет! Вдобавок, этот класс является безымянным — у него отсутствует имя. Ситуация запутывается еще тем, что поначалу мы будто бы приступаем к созданию объекта Contents, а потом, остановившись перед точкой с запятой, говорим: «Стоп, а сюда я подкину определение класса».

Такая необычная форма записи значит буквально следующее: «Создать объект безымянного класса, который унаследован от Contents». Ссылка, которая возвращается при этом из выражения new, автоматически повышается до базового типа Contents. Синтаксис записи безымянного внутреннего класса является укороченной формой записи такой конструкции:

//: innerclasses/Parcel7b.java

II Расширенная версия Parcel7.java

public class Parcel7b {

class MyContents implements Contents { private int i = 11; public int valueO { return i; }

}

public Contents contents О { return new MyContentsО; } public static void main(String[] args) { Parcel 7b p = new Parcel7b; Contents с = p contentsO;

}

} ///-

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

// innerclasses/Parcel8 java

// Вызов конструктора базового класса.

public class Parcel8 { продолжение &

public Wrapping wrapping(int x) {

// Вызов конструктора базового класса, return new Wrapping(x) { // аргумент конструктора public int valueO {

return super.valueO * 47;

}

}; // Требуется точка с запятой

}

public static void main(String[] args) { Parcel8 p = new Parcel80; Wrapping w = p.wrapping(lO);

}

} ///:-

Требуемый аргумент просто передается в конструктор базового класса, как в рассмотренном примере х в выражении new Wrapping(x). Хотя это обычный класс с реализацией, Wrapping также используется в качестве общего «интерфейса» для своих производных классов:

II: innerclasses/Wrapping.java public class Wrapping { private int i,

public Wrapping(int x) { i = x; } public int valueO { return i; } } ///:-

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

Точка с запятой в конце безымянного внутреннего класса поставлена вовсе не для того, чтобы обозначить конец тела класса (как делается в С++). Вместо этого она указывает на конец выражения, в котором содержится внутренний класс. Таким образом, в данном случае ее использование ничем не отличается от обычного.

Инициализацию также можно провести в точке определения полей безымянного класса:

II: innerclasses/Parcel9.java

II Безымянный внутренний класс, выполняющий инициализацию. II Более короткая версия программы Parcel5 java

public class Parcel9 {

II Для использования в безымянном внутреннем классе II аргументы должны быть неизменны (final); public Destination destination(final String dest) { return new Destination0 {

private String label = dest;

public String readLabelO { return label; }

}:

}

public static void main(String[] args) { Parcel9 p = new Parcel90; Destination d = p.destinationCTacMaHHfl").

}

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

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

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

Винокуров Юрий
29. Кодекс Охотника
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Охотника. Книга XXIX

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

Ву Тим
Деловая литература:
о бизнесе популярно
5.00
рейтинг книги
Главный рубильник. Расцвет и гибель информационных империй от радио до интернета

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

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

Адвокат империи

Карелин Сергей Витальевич
1. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
фэнтези
5.75
рейтинг книги
Адвокат империи

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

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

Зодчий. Книга I

Погуляй Юрий Александрович
1. Зодчий Империи
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Зодчий. Книга I

Цикл "Идеальный мир для Лекаря". Компиляция. Книги 1-30

Сапфир Олег
Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Цикл Идеальный мир для Лекаря. Компиляция. Книги 1-30

Я — Легион

Злобин Михаил
3. О чем молчат могилы
Фантастика:
боевая фантастика
7.88
рейтинг книги
Я — Легион

Ты - наша

Зайцева Мария
1. Наша
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Ты - наша

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

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

Аландская Звезда

Перунов Антон
6. Константин
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Аландская Звезда

Имперец. Том 4

Романов Михаил Яковлевич
3. Имперец
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Имперец. Том 4

Хроники Тириса. Книга 3

Маханенко Василий Михайлович
3. Хроники Тириса
Фантастика:
боевая фантастика
космическая фантастика
фантастика: прочее
5.00
рейтинг книги
Хроники Тириса. Книга 3

Неучтенный элемент. Том 11

NikL
11. Антимаг. Вне системы
Фантастика:
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 11