Я хочу спросить Вас, почему нам нужны внутренние классы и почему мы используем их?
Я знаю, как использовать внутренние классы, но я не знаю почему..
Некоторые внутренние классы доступны публично (например, Map.Entry
в Java), но это скорее исключение, чем норма.
Внутренние классы, по сути, являются деталью реализации.
Например, Swing широко использует внутренние классы для прослушивателей событий. Без них вы бы в конечном итоге засорили глобальное пространство имен кучей классов, которые в противном случае вам не нужно было бы видеть (что может затруднить определение их цели).
По сути, внутренние классы - это форма области видимости. Доступ к пакету скрывает классы вне пакета. Частные внутренние классы скрывают этот класс извне этого класса.
Внутренние классы в Java также заменяют отсутствие указателей на функции или делегатов методов (которые есть в C #) или замыканий. Они являются средством передачи функции другой функции. Например, в классе Executor
у вас есть:
void execute(Runnable r);
, чтобы вы могли передать метод. В C / C ++ это может быть достигнуто с помощью:
void execute(void (*run)());
является указателем на функцию.
Большую часть времени я использую внутренние классы потому, что внутренние классы наиболее близки к концепции закрытия , доступной в других языках. Это позволяет создавать и работать с объектом внутренней вложенной области видимости, который имеет доступ к переменным внешней области видимости. Это часто бывает полезно при создании обратных вызовов (например, при определении различных Listener
в Swing) среди прочего.
Я использую их для определения области видимости, например, если у меня есть класс ebook и ebookPrice, я заключаю ebookPrice между классом ebook, поскольку он связан с ним и может использоваться только (по крайней мере, концептуально) внутри него.
ebookPrice может наследовать от Price, которая находится в более высокой области и связана со всеми остальными классами.
(Всего два цента).
Этот фрагмент из википедии может помочь вам понять, зачем нам нужен внутренний класс:
Экземпляр обычного или верхнего Уровень уровня может существовать самостоятельно . Напротив, экземпляр внутреннего класса не может быть создан без привязки к классу верхнего уровня.
Возьмем абстрактное понятие автомобиля с четырьмя колесами. У наших колес есть особенность, которая зависит от того, что они являются частью нашего автомобиля. Это понятие не представляет колеса как колеса в более общей форме, которые могли бы быть частью транспортного средства. Вместо этого он представляет их как специфические для этого. Мы можем смоделировать это понятие с помощью внутренних классов следующим образом:
У нас есть класс верхнего уровня Car. Экземпляры класса Car состоят из четырех экземпляров класса Wheel.Эта конкретная реализация Wheel специфична для автомобиля, поэтому код не моделирует общее понятие Wheel, которое лучше было бы представить как класс верхнего уровня. Следовательно, он семантически связан с классом Car, а код Wheel каким-то образом связан с его внешним классом.
Внутренние классы предоставляют нам механизм для точного моделирования этой связи. Мы говорим, что наш класс колес - это Car.Wheel, Car - это класс верхнего уровня, а Wheel - внутренний класс.
Таким образом, внутренние классы допускают объектную ориентацию определенных частей программы, которые в противном случае не были бы инкапсулированы в класс.
Анонимные внутренние классы в Java - это способ использования шаблон адаптера.
interface Bar
{
public void bar();
}
class Foo
{
public void foo()
{
// do something relevant
}
// it happens that foo() defines the same contract (or a compatible one) as
// Bar.bar(); with an anonymous inner class we can adapt Foo to the Bar
// interface
public Bar asBar()
{
// return an instance of an anonymous inner class that implements
// the Bar inteface
return new Bar()
{
public void bar()
{
// from an inner class, we can access the enclosing class methods
// as the "this pointers" are "linked"
foo();
}
};
}
}
В Java убедитесь, что вы понимаете разницу между внутренним классом и вложенным классом :
внутренний класс связан с экземпляром своего включающего класса и {{1} } имеет прямой доступ к методам и полям этого объекта
. В C # нет внутренних классов в смысле Java, только вложенные классы.
См. Также этот Пример внутреннего класса .
Есть языки, которые переводят внутренние классы на совершенно другой уровень, например, бета и новояз. В этих языках вложенность классов служит упаковкой (т.е. пакетов нет).
Чтобы хорошо осветить это видение, обратитесь к «Сколько концепций для модулей нам нужно?» в блоге объектных команд. См. Также работу Гилада Браха в его блоге ...