Подтвердить что ты не робот

Когда использовать внутренние классы в Java для вспомогательных классов

Если у меня есть класс, вместе со вспомогательным классом, который выполняет некоторые из его функций, имеет смысл сделать его внутренним классом.

    public class Foo {
       private FooHelper helper;

       // constructor & any other logic

       public void doSomeThing() {
         helper.do();
       }
    }

    public class FooHelper {
        public void do() {
         // code
        }
    }

В приведенном выше случае имеет смысл сделать FooHelper внутренним классом? Извините, если это звучит глупо, но я немного запутался в случаях использования.

4b9b3361

Ответ 1

Да, имеет смысл сделать его внутренним классом. Если никакие другие классы не нуждаются в этом, сделайте его закрытым. Если он не требует эксклюзивного доступа к членам внешнего класса, сделайте его статическим вложенным классом, потому что тогда ему потребуется меньше места в памяти.

Ознакомьтесь с рекомендацией официального учебника -

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

Ответ 2

Если вы считаете, что FooHelper будет вообще не полезным для других классов, чем Foo, тогда имеет смысл сделать его как private внутренний класс Foo. Один пример такого типа дизайна можно найти в HashMap, где он определяет частный внутренний класс KeySet

В противном случае это выглядит как экземпляр private.

Ответ 3

Из документов JAVA SE

Зачем использовать вложенные классы?

Это способ логически группировать классы, которые используются только в одном месте: Если класс полезен только для одного другого класса, тогда логично вставлять его в этот класс и поддерживать два вместе. Вложение таких "вспомогательных классов" делает их пакет более упорядоченным.

Он увеличивает инкапсуляцию: Рассмотрим два класса верхнего уровня: A и B, где B требуется доступ к членам A, которые в противном случае были бы объявлены частными. Скрывая класс B в классе A, члены A могут быть объявлены частными и B может получить к ним доступ. Кроме того, сам B может быть скрыт от внешнего мира.

Итак, имеет смысл использовать FooHelper как внутренний класс.

Ответ 4

Вот несколько примеров использования внутренних классов.

  • Внутренние классы используются для получения функциональности, которая может получить объект лучше, чем метод.
  • Они могут использоваться в случае, когда требуется набор из нескольких операций, и вероятность повторного использования высока внутри класса, и они не будут доступны, кроме методов вне внешнего класса.
  • Внутренние классы сделаны, чтобы достигнуть множественного наследования также.
  • Внутренние классы используются, когда они полезны в контексте класса.
  • Они используются для разделения логики внутри классов.

Так что, если у вас есть требования, соответствующие вышеуказанным пунктам, можно использовать внутренние классы. Всегда лучше сделать внутренний класс private чтобы предотвратить доступ других классов. В вашем случае использование внутренних классов полезно, чтобы сделать код читаемым и отделить логику от внешнего класса.

Ответ 5

Внутренние классы имеют смысл, когда они крошечные и не нуждаются в именах. Слушатели в GUI являются классическими примерами, где они имеют смысл.

Если класс большой и важный, он должен быть назван и помещен в отдельный файл.

Классы-слушатели в обычных примерах GUI делают одну крошечную вещь, обычно просто отправляют какую-то другую функцию для выполнения реальной работы.

Я также часто использую статические вложенные классы (которые технически не являются внутренними классами) для классов, которые используются только в контексте другого класса - Map.Entry - хороший пример этого. Он используется только в сочетании с Картой, поэтому определение элемента Entry в составе интерфейса карты имеет организационный смысл.

Обычно я не использую много других типов вложенных классов, таких как нестатические классы-члены и локальные классы. Но иногда они приходят в полезное время. Для хорошего примера законного использования классов-членов см. Исходный код для LinkedList.ListItr. Это частный внутренний класс, целью которого является обеспечить реализацию ListIterator для LinkedList. Для этого полезно иметь доступ к личным данным внутри LinkedList. Чтобы достичь этого, используя только классы верхнего уровня, было бы необходимо выставить больше публичных методов в LinkedList, чтобы позволить ListIterator получить базовую реализацию LinkedList. Вместо этого использование внутреннего класса позволяет LinkedList сохранять свою реализацию как таковой, как и должно быть.

Ответ 6

Да, преимущество использования внутреннего класса заключается в доступе к членам внешнего класса. В вашем случае, если вы считаете, что ваш FooHelper не должен использоваться каким-либо другим классом, вы можете сделать его внутренним классом.

Чтобы проверить полезность внутреннего класса, просмотрите примеры AWT. Анонимные внутренние классы широко используются в обработчиках событий.

Ответ 7

Что такое область Foo? Когда Foo класс модели домена с его собственным жизненным циклом и helper является общей услугой, похоже, смешивание двух объектов с очень разными возможностями/Жизненный цикл.

Обычно у домена есть собственный жизненный цикл от создания, настойчивости к нему GC. С другой стороны, помощник или служба являются либо статическими, либо более динамичными, а жизненный цикл равен всему приложению, например. spring bean.

Как только ваш объект домена будет содержать ссылку на услугу, он может вызвать серьезные проблемы. Например. каждый вызов в репозиторий Get должен указывать ссылку на эту услугу на объект домена. Я бы рекомендовал избежать этого шаблона.

Для меня не очевидно, кто сделает для вас пример helper.

Ответ 8

Hild, Да, во многих случаях имеет смысл использовать внутренний класс.

Подумайте об этом так: внутренний класс будет жить и умирать с внешним классом, поэтому любые функциональные возможности, которые особенно необходимы для внешнего класса, могут быть добавлены во внутренний класс. Популярные примеры - Слушатели в большинстве случаев - Типы KeyListeners, MouseListeners, eventListeners.

Классы в Java позволяют вам иметь определенную функциональность, но иногда вам может потребоваться отдельная специализированная функциональность, но она также должна быть тесно связана с классом, который вы разрабатываете.

Существует четыре типа внутренних классов. Простой поиск в Google поможет вам узнать больше о них.

Ответ 9

Вложенные классы позволяют вам логически группировать классы, которые используются только в одном месте, увеличивают использование инкапсуляции и создают более читаемый и поддерживаемый код. Локальные классы, анонимные классы.

http://docs.oracle.com/javase/tutorial/java/javaOO/whentouse.html

Ответ 10

Существует два дополнительных типа внутренних классов. Вы можете объявить внутренний класс внутри тела метода. Эти классы называются локальными классами. Вы также можете объявить внутренний класс внутри тела метода без присвоения имени классу. Эти классы известны как анонимные классы.

Локальный класс: используйте его, если вам нужно создать несколько экземпляров класса, получить доступ к его конструктору или ввести новый именованный тип (потому что, например, вам нужно вызвать дополнительные методы позже).

Анонимный класс: используйте его, если вам нужно объявить поля или дополнительные методы.

Ответ 11

Когда использовать внутренние классы?

  1. Внутренний класс не требует никакого дополнительного или отдельного файла для размещения.
  2. Внутренние классы сравнительно малы и тесно связаны с "родительским" классом или "внешним" классом. Избегает множества вспомогательных классов и подходит для объяснения принципа ограничения OOD.
  3. Весь код в одном и том же файле повышает читабельность и повышает производительность (например, онлайн-код). Их значение растет в кодировании и рассматривается как хорошая практика.
  4. Анонимные внутренние классы очень полезны, когда вы хотите определить обратные вызовы на лету.
  5. Объект внутреннего класса может получить доступ к реализации объекта, который создал it-, ВКЛЮЧАЯ приватные данные.
  6. Внутренние классы могут получить доступ к поведению своего родительского класса, в том числе частного.

Ответ 12

Необоснованные причины использования вложенных классов:

1) Это способ логически сгруппировать классы, которые используются только в одном месте: если класс полезен только для одного другого класса, то логично встраивать его в этот класс и хранить их вместе. Вложение таких "вспомогательных классов" делает их пакет более упорядоченным.

2) Это увеличивает инкапсуляцию: рассмотрим два класса верхнего уровня, A и B, где B нужен доступ к членам A, которые в противном случае были бы объявлены закрытыми. Скрывая класс B в классе A, члены A могут быть объявлены частными, и B может получить к ним доступ. Кроме того, сам B может быть скрыт от внешнего мира.

3) Это может привести к более удобочитаемому и поддерживаемому коду: вложение небольших классов в классы верхнего уровня размещает код ближе к месту его использования.