Ответ 1
Я делаю это так же, как и вы, если нет ничего, что уходит в одну строку. Возможно, добавьте комментарий к большому блоку "однострочных реализаций".
Скажем, у меня есть класс 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-кодер, поэтому решил, что спрошу, существует ли соглашение. Мысли?
Я делаю это так же, как и вы, если нет ничего, что уходит в одну строку. Возможно, добавьте комментарий к большому блоку "однострочных реализаций".
В этом конкретном случае вы должны следовать советам wilums2 и расширять MouseAdapter вместо реализации MouseListener. Назначение этих классов адаптеров заключается в том, что вам не нужно предоставлять пустые реализации, когда вы только реализуете некоторые из методов интерфейса.
В общем случае, короткий ответ - "нет", стандартного соглашения о том, как документировать пустые методы, нет, хотя я обычно использую что-то вроде
@Override
void foo() {
// No implementation necessary
}
Используйте MouseAdapter
В общем, то, о чем вы говорите, является расширением шаблона нулевого объекта. Вы определяете объект 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
Есть несколько способов сделать это. Соглашения Java Java p6.4 (стр. 11) говорит, что пустые методы должны выглядеть как
public void empty() {}
Существует также документ Стив Йоханан, написанный в 2003 году ant он говорит
public void empty()
{
}
Хотя я не нашел никакого соглашения для "пустого метода в качестве заглушки интерфейса". Итак, как вывод, нет стандартизированного способа сделать это. Некоторые предпочитают оставлять комментарий, некоторые предпочитают делать его одной строкой, некоторые пишут его как любой другой метод с пустым телом.
MouseAdapter отлично подходит для этого конкретного случая, и идиома адаптера в целом отличная. Адаптер имеет пустые реализации всех методов интерфейса, позволяя вам подклассы и применять только те методы, которые относятся к вашему классу. Адаптер может альтернативно, как предлагает Эндрю Хэр, бросить NotImplementedException.
Цель слушателя - быть уведомленным о некоторых событиях. Если интерфейс прослушивателя содержит больше обратных вызовов методов, чем вам нужно, просто игнорируйте те, которые вам не нужны. В вашем случае MouseAdapter
был разработан для этой цели. Сделайте не бросок UnsupportedOperationException
, поскольку вызывающий абонент, скорее всего, не ожидает исключения. Это также, скорее всего, нарушает контракт интерфейса слушателя, поскольку ожидается, что каждый метод будет реализован.
Думаю, я бы описал это как "не-op-реализации" или, возможно, использовал термин "адаптер". Как отмечали другие, Java предоставляет класс MouseAdapter
, который делает то, что вы хотите. Строго говоря, это не совсем относится к определению шаблона адаптера, который превращает один API в другой, но, честно говоря, я склонен прагматично описывать такие вещи.
Возможно, самое важное, что нужно сделать, - это понять, что вы намерены использовать метод не для реализации. В конкретном случае MouseAdapter
вы, вероятно, не хотите обойти бросок UnsupportedOperationException
, но в целом это, вероятно, хороший сигнал, который вы не собираетесь предоставлять. Обычно требуется комментарий в исходном коде (или, лучше, документация метода), чтобы объяснить, почему вы не реализуете интерфейс полностью.
Я не думаю, что это особенно важно. Для моих личных вкусов мне не нравится видеть закрывающую скобу рядом с отверстием, которая дает:
public void mouseEntered(MouseEvent e) {
}
Немного пуст, но все в порядке. В случае возвращаемого значения мы можем заставить его выглядеть согласованным, с которым вы не получаете стиль []
.
Но когда дело доходит до редкого случая в циклах, мне нравится точка с запятой:
// Made up example.
while (++i < len && str.charAt(i) != '\0') {
;
}
Что даст:
public void mouseEntered(MouseEvent e) {
;
}
В случае предложений catch
у вас должно быть хорошее оправдание в комментарии (возможно, отключение прерывания).
Я нашел это, ища этот точный вопрос. Я использую свиток, где мне нужно 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;}
У этого есть много параметров, поэтому он выглядит не так хорошо, как на одной строке, но вы получаете идею.