Анонимные внутренние классы: когда они (не) уместны? - PullRequest
3 голосов
/ 12 декабря 2011

Возьмите следующий пример.Есть объект, который я хочу использовать, назовите его Doodad.Элементы Doodad плохо реализовали обработку событий браузера.Типичный экземпляр Doodad будет Doodad someDoodad = new Doodad();.Очевидно, это не соответствует моим потребностям из-за плохой обработки событий.Уместно ли мне переопределить метод onBrowserEvent(), например, так:

Doodad someDoodad = new Doodad() {
@Override
  public void onBrowserEvent(Event event) {
      switch (DOM.eventGetType(event)) {
          case Event.ONDBLCLICK:
          case Event.ONFOCUS:
          case Event.ONCLICK:
              if (!isEnabled()) {
                  return;
              }
              break;
      }
      super.onBrowserEvent(event);
  }
};

Очевидно, что это простой пример, но когда я не хочу использовать анонимный внутренний класс?Это когда-либо явно запрещено или невозможно?

Я вижу много ответов на первый вопрос, но пока ни один из ответов не отвечает на второй: Это когда-либо явно запрещено или невозможно использовать?анонимный внутренний класс?

Ответы [ 7 ]

6 голосов
/ 12 декабря 2011

Обычно лучшее использование анонимных внутренних классов - это когда вы хотите создать только один экземпляр конкретной реализации этого класса.И когда реализация довольно проста.В идеале он должен содержать 1-2 строки кода.

В вашем случае все в порядке, хотя ваш метод onBrowserEvent() длиннее 2 строк.

3 голосов
/ 12 декабря 2011

Анонимные внутренние классы - это синтаксис Java для создания замыканий.Вот примерный пример:

interface Adder {
  int add(int arg);
}

...

Adder createAdder(int n) {
   final int nf = n;
   return new Adder() { 
       int add(int arg) { return arg + nf; } 
   }
}

Метод createAdder создает, по сути, функцию, используя замыкание для захвата переданного значения n.Замыкания важны в функциональном программировании, которое пытается превратить его в мейнстрим.Вот почему все кричат ​​о том, что нам нужны «настоящие» замыкания в Java (то есть в основном лучше синтаксис, чем в моем примере).

(Конечно, я не отвечаю на заданный вопрос; я думаю, что яПоговорка состоит в том, что анонимные классы хороши для того, что я описал выше. Для почти всего остального я бы создал именованный внутренний класс, потому что если что-то имя является самодокументированным и, на мой взгляд, легче для чтения)

1 голос
/ 12 декабря 2011

Я бы предложил анонимные классы, когда он реализует один метод и / или заполнен на половину экрана.

Если у анонимного есть нетривиальный кусок кода, то стоит иметь именованный класс IMHO.

1 голос
/ 12 декабря 2011

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

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

Я не уверен, что понимаю ваш вопрос конкретно, надеюсь, эта информация поможет вам найти ваш ответ.Не стесняйтесь задавать дополнительные вопросы.

0 голосов
/ 12 декабря 2011

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

В частности, вы можете создать эти улучшенные Doodads в нескольких разных местах.И что произойдет, если обработка событий будет обновлена ​​и улучшена в будущем?Вы захотите удалить все эти улучшенные Doodads и использовать правильную реализацию.Попытка найти всех своих анонимных Doodads может быть утомительной или хитрой.Принимая во внимание, что если у вас есть отдельный именованный класс, рефакторинг этого класса будет простым.

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

Например.

public class ImprovedBrowserEventHandlingDoodad extends Doodad {
    ...
}

Все, чтонапоминает, что замыкание обычно является хорошим кандидатом для использования анонимного класса

например.

new Thread(new Runnable() {
    @Override
    public void run() {
        doSomething();
    }
}).start();

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

Обработчики событий для графических интерфейсов типичны для использования анонимных классов, поскольку их использование ограничено тем, как разрабатывается графический интерфейс, и нет необходимости создаватьотдельный экземпляр обработчика события вне определенного компонента, который его использует.Например, когда вы наводите курсор мыши на полосу прокрутки, ее внешний вид обычно меняется.Ничто другое в программе не вызовет этого изменения, и обычно обработчик события будет состоять из пары строк, сообщающих полосе прокрутки, например, изменить ее внешний вид.scrollbar.setMouseOverEffect(true);.

0 голосов
/ 12 декабря 2011

Я использую анонимный внутренний класс только тогда, когда он содержит очень небольшое количество кода. Причина в том, что IMO загромождает код и делает его менее читабельным.

Если требуется больше кода, я предпочитаю создавать новый класс, расширяющий базовый класс (в данном случае 'Doodad ()'

0 голосов
/ 12 декабря 2011

Мой дубль:

Анонимные внутренние классы: обратный вызов из одной функции (чтобы вы не писали код дважды)

Именованные внутренние классы: обратные вызовы от нескольких функций (или класса, который вам нужен только для внутренней логики родительского класса)

...