WikiSort.ru - Программирование

ПОИСК ПО САЙТУ | о проекте

Внутренний, или вложенный класс (англ. inner class) — в объектно-ориентированном программировании класс, целиком определённый внутри другого класса.

Вложенные классы поддерживаются в языке программирования Java, начиная с версии 1.1, С# и других языках на платформе .NET, а также в языке программирования D и в C++.

Обзор

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

Внутренние классы в языке Java

В 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 (ссылка на страницу книги)

Примечания

  1. Oracle. The Java™ Tutorials. Inner classes. Oracle Documentation.
  2. Local Classes (The Java™ Tutorials > Learning the Java Language > Classes and Objects). docs.oracle.com. Проверено 12 апреля 2016.

Ссылки

Данная страница на сайте WikiSort.ru содержит текст со страницы сайта "Википедия".

Если Вы хотите её отредактировать, то можете сделать это на странице редактирования в Википедии.

Если сделанные Вами правки не будут кем-нибудь удалены, то через несколько дней они появятся на сайте WikiSort.ru .




Текст в блоке "Читать" взят с сайта "Википедия" и доступен по лицензии Creative Commons Attribution-ShareAlike; в отдельных случаях могут действовать дополнительные условия.

Другой контент может иметь иную лицензию. Перед использованием материалов сайта WikiSort.ru внимательно изучите правила лицензирования конкретных элементов наполнения сайта.

2019-2024
WikiSort.ru - проект по пересортировке и дополнению контента Википедии