Внутренний класс
- 1 year ago
- 0
- 0
Внутренний , или вложенный класс ( англ. inner class) — в объектно-ориентированном программировании класс , целиком определённый внутри другого класса.
Вложенные классы поддерживаются в языке программирования Java , начиная с версии 1.1, С# и других языках на платформе .NET, а также в языке программирования D и в C++ .
Экземпляр обычного (внешнего) класса может существовать как независимый объект. Для его существования не требуется обязательное наличие определений других классов или их экземпляров. В случае внутреннего класса, его экземпляр не может существовать без привязки к включающему его классу верхнего уровня либо его экземпляру.
В Java существуют 4 типа внутренних (inner) классов:
Экземпляр внутреннего класса может существовать только тогда, когда существует конкретный экземпляр внешнего класса. Такая логическая связь обусловливает синтаксис создания объектов: сначала создаётся объект внешнего класса, позднее на его основе создаётся объект внутреннего класса.
Внутренние нестатические классы описываются внутри основного внешнего класса. Экземпляры таких классов имеют доступ к
public
,
protected
,
default
и
private
полям внешнего класса. А также статическим и нестатическим методам внешнего экземпляра с любыми модификаторами доступа. За счёт того, что экземпляры внутреннего класса всегда логически привязаны к экземплярам окружающего класса, они не могут содержать (хотя могут наследовать от предка) определение статических полей, методов и классов (кроме констант).
Пример объявления внутреннего класса:
class OuterClass { private int outerField; class InnerClass { int getOuterField() { return OuterClass.this.outerField; // эта строчка кода демонстрирует концепцию замыкания. } } }
Создание описанного класса можно описать следующим блоком кода:
OuterClass.InnerClass inner = new OuterClass().new InnerClass();
Декларируются внутри основного класса и обозначаются ключевым словом
static
. Объекты таких классов не имеют доступа к членам внешнего класса за исключением статических. Это обусловлено тем, что для создания такого класса не используется конкретный объект внешнего класса и в момент исполнения кода внутреннего класса, объекта внешнего может вовсе не быть. Экземпляры статических вложенных классов могут содержать статические поля, методы и классы, в отличие от других типов внутренних классов.
Пример объявления вложенного статического класса:
class OuterClass { private int outerField; static int staticOuterField; static class StaticInnerClass { int getOuterField() { return OuterClass.this.outerField; // эта строчка кода приведёт к ошибке компиляции. } int getStaticOuterField() { return OuterClass.staticOuterField; // эта строчка кода корректна. } } }
Создание описанного статического вложенного класса можно описать следующим блоком кода:
OuterClass.StaticInnerClass staticInner = new OuterClass.StaticInnerClass();
Декларируются внутри методов основного класса. Могут быть использованы только внутри этих методов. Имеют доступ к членам внешнего класса. Имеют доступ как к локальным переменным, так и к параметрам метода при одном условии - переменные и параметры, используемые локальным классом, должны быть задекларированы
final
. Не могут содержать определение (но могут наследовать) статических полей, методов и классов (кроме констант).
Пример:
class OuterClass { private int outerField; void methodWithLocalClass(final int finalParameter) { int notFinalVar = 0; notFinalVar++; class InnerLocalClass { void getOuterField() { int a = notFinalVar; // эта строчка кода приведёт к ошибке компиляции. no-final переменные вне контекста недоступны. int b = OuterClass.this.outerField; // эта строчка кода демонстрирует обращение члену обрамляющего класса. } int getParameter() { return finalParameter; // эта строчка кода демонстрирует обращение к final переменной вне контекста. } } } }
Создание описанного локального класса возможно только внутри самого метода строго ниже кода объявления самого класса. Пример кода создания:
InnerLocalClass innerLocal = new InnerLocalClass();
Декларируются внутри методов основного класса. Могут быть использованы только внутри этих методов. В отличие от локальных классов, анонимные классы не имеют названия. Главное требование к анонимному классу - он должен наследовать существующий класс или реализовывать существующий интерфейс. Не могут содержать определение (но могут наследовать) статических полей, методов и классов (кроме констант). Пример:
class OuterClass { /** * При определении анонимного класса применен полиморфизм — переменная listener * содержит экземпляр анонимного класса, реализующего существующий * интерфейс ActionListener. **/ void methodWithAnonymousClass(final int interval) { ActionListener listener = new ActionListener() { public void actionPerformed(ActionEvent event) { System.out.println("Эта строка выводится на экран каждые " + interval + " секунд."); } }; Timer t = new Timer(interval, listener); // объект анонимного класса использован внутри метода. t.start(); } }
В PHP 7 есть механизм описания анонимных классов, однако, в отличие от Java, анонимные классы не обязаны наследовать существующий класс или реализовывать существующий интерфейс , что достигается благодаря динамической природе языка. Пример:
// Pre PHP 7 code class Logger { public function log($msg) { echo $msg; } } $util->setLogger(new Logger()); // PHP 7+ code $util->setLogger(new class { public function log($msg) { echo $msg; } });
Cay S. Horstmann and Gary Cornell, Core Java , eighth edition (Volume I). Prentice Hall, 2003. ISBN 978-0132354769 ()