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

Есть ли идиома в Java для пустых методов, которые существуют для удовлетворения интерфейса?

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

Моя склонность заключалась в том, чтобы написать следующее:

@Override
public void mouseClicked(MouseEvent e) {
    // (...) <-- actual code here
}

@Override
public void mouseEntered(MouseEvent e) {
    // Do nothing.  Exists to satisfy MouseListener interface.
}

@Override
public void mouseExited(MouseEvent e) {
    // Do nothing.  Exists to satisfy MouseListener interface.
}

@Override
public void mousePressed(MouseEvent e) {
    // Do nothing.  Exists to satisfy MouseListener interface.
}

@Override
public void mouseReleased(MouseEvent e) {
    // Do nothing.  Exists to satisfy MouseListener interface.
}

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

public void mouseClicked(MouseEvent e) {
    // (...) <-- actual code here
}

public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}

Я вообще в порядке с этим, и я понимаю намерение автора, но он становится очень уродливым, когда добавляются примечания (рекомендуется) @Override.

Я не очень опытный Java-кодер, поэтому решил, что спрошу, существует ли соглашение. Мысли?

4b9b3361

Ответ 1

Я делаю это так же, как и вы, если нет ничего, что уходит в одну строку. Возможно, добавьте комментарий к большому блоку "однострочных реализаций".

Ответ 2

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

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

@Override
void foo() {
  // No implementation necessary
}

Ответ 3

Используйте MouseAdapter

Ответ 4

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

В качестве примера способа автоматизации этого в моих JavaDude Bean Аннотации (http://code.google.com/p/javadude/wiki/Annotations) вы можете сделать что-то вроде следующие. [ПРИМЕЧАНИЕ: я бы не рекомендовал делать это для MouseListener, поскольку MouseAdapter уже существует, и вы можете просто подклассифицировать его... Ниже приведено полезное для других больших интерфейсов, где вы хотите реализовать только несколько методов выбора]

@Bean(nullObjectImplementations = @NullObject(type=MouseListener.class))
public class MyMouseHandler extends MyMouseHandlerGen {
    public void mouseClicked(MouseEvent e) {
        // your handling of a MouseClick
    }
}

Затем вы можете использовать MyMouseHandler для обработки щелчка. =

Примечание. MouseAdapter был действительно плохим выбором для имени класса в JRE/JDK. Это не экземпляр шаблона адаптера GoF; это действительно реализация Null Object MouseListener.

BTW: вы можете поместить @Override в ту же строку, что и объявление метода - для вашего примера вы можете иметь

@Override public void mousePressed(MouseEvent e) { /* not needed */ }
// et al

Ответ 5

Есть несколько способов сделать это. Соглашения Java Java p6.4 (стр. 11) говорит, что пустые методы должны выглядеть как

public void empty() {}

Существует также документ Стив Йоханан, написанный в 2003 году ant он говорит

public void empty()
{
}

Хотя я не нашел никакого соглашения для "пустого метода в качестве заглушки интерфейса". Итак, как вывод, нет стандартизированного способа сделать это. Некоторые предпочитают оставлять комментарий, некоторые предпочитают делать его одной строкой, некоторые пишут его как любой другой метод с пустым телом.

Ответ 6

MouseAdapter отлично подходит для этого конкретного случая, и идиома адаптера в целом отличная. Адаптер имеет пустые реализации всех методов интерфейса, позволяя вам подклассы и применять только те методы, которые относятся к вашему классу. Адаптер может альтернативно, как предлагает Эндрю Хэр, бросить NotImplementedException.

Ответ 7

Цель слушателя - быть уведомленным о некоторых событиях. Если интерфейс прослушивателя содержит больше обратных вызовов методов, чем вам нужно, просто игнорируйте те, которые вам не нужны. В вашем случае MouseAdapter был разработан для этой цели. Сделайте не бросок UnsupportedOperationException, поскольку вызывающий абонент, скорее всего, не ожидает исключения. Это также, скорее всего, нарушает контракт интерфейса слушателя, поскольку ожидается, что каждый метод будет реализован.

Ответ 8

Думаю, я бы описал это как "не-op-реализации" или, возможно, использовал термин "адаптер". Как отмечали другие, Java предоставляет класс MouseAdapter, который делает то, что вы хотите. Строго говоря, это не совсем относится к определению шаблона адаптера, который превращает один API в другой, но, честно говоря, я склонен прагматично описывать такие вещи.

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

Ответ 9

Я не думаю, что это особенно важно. Для моих личных вкусов мне не нравится видеть закрывающую скобу рядом с отверстием, которая дает:

public void mouseEntered(MouseEvent e) {
}

Немного пуст, но все в порядке. В случае возвращаемого значения мы можем заставить его выглядеть согласованным, с которым вы не получаете стиль [].

Но когда дело доходит до редкого случая в циклах, мне нравится точка с запятой:

// Made up example.
while (++i < len && str.charAt(i) != '\0') {
    ;
}

Что даст:

public void mouseEntered(MouseEvent e) {
    ;
}

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

Ответ 10

Я нашел это, ища этот точный вопрос. Я использую свиток, где мне нужно onScrollStateChanged, но не onScroll. Я склонялся к:

@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
            int totalItemCount) {
    return;         
} 

Однако мне нравится второй пример, который вы даете (с фигурными скобками на одной строке). Он компактен и чист и может последовательно выражать мысль о том, что он намеренно оставлен пустым.

Изменить: это то, на чем я остановился:

@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
            int totalItemCount) {return;}

У этого есть много параметров, поэтому он выглядит не так хорошо, как на одной строке, но вы получаете идею.