2009-05-19 3 views
23

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

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

@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) {} 

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

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

+1

Вы знаете класс MouseAdapter, не так ли? http://java.sun.com/javase/6/docs/api/java/awt/event/MouseAdapter.html –

ответ

5

Использование MouseAdapter

+7

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

+6

Он спрашивает о коэнов, а не о том, какой интерфейс реализовать. –

+0

Расширьте этот класс, чтобы создать прослушиватель MouseEvent и переопределить методы для интересующих событий. (Если вы реализуете интерфейс MouseListener, вам нужно определить все методы в нем. Этот абстрактный класс определяет для всех нулевые методы, поэтому вам нужно только определить методы для событий, которые вам нужны.) Http: // java. sun.com/j2se/1.4.2/docs/api/java/awt/event/MouseAdapter.html –

8

я сделать это так же, как вы делаете, если Тереза ​​ничего не оставлять на одной строке. Возможно, добавьте комментарий к большому блоку «однострочные реализации».

1

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

6

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

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

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

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

+0

Вызывающий также, вероятно, не ожидает, что функция ничего не сделает. Не делая ничего, вы нарушили контракт с интерфейсом, что приведет к странным и чрезвычайно трудным для отладки ошибок. Я бы сказал, выбросьте ошибку, чтобы проблема возникла сразу во время тестирования/использования. Если вы не можете выбросить ошибку, вы должны, по крайней мере, записать предупреждение о том, что была вызвана Неподдерживаемая операция. Не делая абсолютно ничего, может быть дорогостоящей ошибкой (вовремя отлаживая полученные ошибки). (если у вас есть сомнения, по крайней мере, зарегистрируйте его так, чтобы был найден хотя бы хороший намек на ошибки, которые он вызывает). – Tezra

0

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

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

0

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

public void mouseEntered(MouseEvent e) { 
} 

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

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

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

который даст:

public void mouseEntered(MouseEvent e) { 
    ; 
} 

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

5

В общем, речь идет о расширении шаблона нулевого объекта. Вы определяете объект 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 
0

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

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

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

Edit: это то, что я остановился на:

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

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

2

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

public void empty() {} 

Существует также документ, Steve Yohanan написанный в 2003 муравья он говорит

public void empty() 
{ 
} 

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

+0

Спасибо, что на самом деле предоставили ссылку на соглашения о кодировании, подобные запросам OP. – amertkara