Введение
В объектно-ориентированном программировании (ООП) внутренний класс или вложенный класс — это класс, объявленный целиком внутри другого класса или интерфейса. Он отличается от подкласса.
Обзор
Инстанция нормального или класса верхнего уровня может существовать независимо. В отличие от этого, экземпляр внутреннего класса не может быть создан без привязки к классу верхнего уровня. Рассмотрим абстрактное понятие автомобиля с четырьмя колесами. Наши колеса обладают специфической характеристикой, обусловленной тем, что они являются частью именно этого автомобиля. Это понятие не представляет колеса как колеса в более общем виде, которые могли бы быть частью любого транспортного средства. Вместо этого, оно представляет их как специфичные для автомобиля. Мы можем смоделировать это понятие, используя внутренние классы следующим образом: у нас есть класс верхнего уровня Car. Экземпляры класса Car состоят из четырех экземпляров класса Wheel. Эта конкретная реализация Wheel специфична для автомобиля, поэтому код не моделирует общее понятие колеса, которое лучше было бы представить как класс верхнего уровня. Следовательно, он семантически связан с классом Car, а код Wheel в определенной степени связан со своим внешним классом, являясь составной частью автомобиля. Колесо для конкретного автомобиля уникально для этого автомобиля, но в целях обобщения колесо является агрегатной единицей для автомобиля. Внутренние классы предоставляют механизм для точного моделирования этой связи. Мы можем ссылаться на наш класс Wheel как Car.Wheel, где Car – класс верхнего уровня, а Wheel – внутренний класс. Таким образом, внутренние классы позволяют реализовать объектно-ориентированный подход к определенным частям программы, которые в противном случае не были бы инкапсулированы в класс. Более крупные фрагменты кода внутри класса могут быть лучше смоделированы или рефакторингованы как отдельные классы верхнего уровня, а не как внутренние классы. Это сделало бы код более общим в применении и, следовательно, более переиспользуемым, но потенциально может привести к преждевременному обобщению. Это может оказаться более эффективным, если в коде много внутренних классов с общей функциональностью.
We have the top level class Car. Instances of class Car are composed of four instances of the class Wheel. This particular implementation of Wheel is specific to a car, so the code does not model the general notion of a wheel that would be better represented as a top level class. Therefore, it is semantically connected to the class Car and the code of Wheel is in some way coupled to its outer class, being a composition unit of a car. The wheel for a particular car is unique to that car, but for generalization, the wheel is an aggregation unit to the car. Inner classes provide a mechanism to accurately model this connection. We can refer to our Wheel class as Car. Wheel, Car being the top level class and Wheel being the inner class. Inner classes therefore allow for the object orientation of certain parts of the program that would otherwise not be encapsulated into a class. Larger segments of code within a class might be better modeled or refactored as a separate top level class, rather than an inner class. This would make the code more general in its application and therefore more re usable but potentially might be premature generalization. This may prove more effective, if code has many inner classes with the shared functionality.
Языки программирования
Внутренние классы появились в языке программирования Java, начиная с версии 1.1. Вложенные классы также являются особенностью языков программирования D, Visual Basic NET, Ruby, C++ и C#. В Python можно определить класс внутри другого класса, метода или функции. В C++ существуют вложенные классы, аналогичные статическим классам-членам в Java, за исключением того, что они не объявляются с использованием ключевого слова "static". Язык BETA впервые ввел понятие вложенных классов.
Код графического пользовательского интерфейса
Локальные внутренние классы часто используются в Java для определения обратных вызовов в коде графического интерфейса пользователя (GUI). Компоненты могут совместно использовать объект, реализующий интерфейс обработки событий или расширяющий абстрактный класс-адаптер, содержащий код, который должен быть выполнен при возникновении определенного события. Анонимные внутренние классы также применяются, когда код обработки событий используется только одним компонентом и, следовательно, не требует именованной ссылки. Это позволяет избежать создания большого монолитного метода с множеством условий if-else для определения источника события. Такой код часто считается неудобным и сложным для чтения, а использование внутренних классов во всех отношениях предпочтительнее.