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