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编码器,所以我想我会问是否有一个约定。 思考?
我这样做的方式与你一样,如果没有任何东西留在一条线上。 也许在一大块“实施单线”之上发表评论。
在这种特殊情况下,您应该遵循wilums2的建议并扩展MouseAdapter而不是实现MouseListener。 这些适配器类的目的是,当您只实现接口的某些方法时,不必提供空实现。
更一般地说,简短的回答是“不”,没有关于如何记录空方法的标准惯例,尽管我通常使用类似的东西
@Override void foo() { // No implementation necessary }
使用MouseAdapter
一般来说,你所说的是Null对象模式的扩展。 你正在定义一个Null对象并通过仅覆盖你关心的方法来扩展它。
作为自动化方法的一个示例,在我的JavaDude Bean Annotations( 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来处理单击。=
注意:对于JRE / JDK中类的名称,MouseAdapter是一个非常糟糕的选择。 它不是GoF适配器模式的实例; 它实际上是MouseListener的Null Object实现。
顺便说一句:您可以将@Override放在与方法声明相同的行上 – 对于您可以拥有的示例
@Override public void mousePressed(MouseEvent e) { /* not needed */ } // et al
有几种方法可以做到这一点。 Oracle java约定 p6.4(第11页)说空方法应该是这样的
public void empty() {}
史蒂夫·约哈南 ( Steve Yohanan)在2003年撰写了一份文件
public void empty() { }
虽然我没有找到任何“空方法作为接口存根”的约定。 因此,作为结论,没有标准化的方法来做到这一点。 有些人喜欢留言,有些人喜欢把它作为单行,有些人则把它写成任何其他方法,留空。
MouseAdapter非常适合这种特殊情况,并且适配器习惯用法通常很棒。 适配器具有接口的所有方法的空实现,允许您子类化并仅实现与您的类相关的那些方法。 另外,正如Andrew Hare建议的那样,适配器可以抛出NotImplementedException。
监听器的目的是通知某些事件。 如果侦听器接口包含的方法回调多于您需要的,则只需忽略您不关心的方法。 在您的情况下, MouseAdapter
是为此目的而设计的。 不要抛出UnsupportedOperationException
因为调用者很可能不期望exception。 它也很可能违反了侦听器接口的合同,因为预计每种方法都会被实现。
我想我会将其描述为“无操作实现”或者可能使用术语“适配器”。 正如其他人所说,Java提供了一个MouseAdapter
类,它MouseAdapter
您的需求。 严格来说,它并不完全属于适配器模式的定义,它将一个API转换为另一个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;}
这一个有很多参数,所以它看起来不像一条线,但你明白了。