27

假设我有一个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 编码器,所以我想我会问是否有约定。想法?

4

10 回答 10

11

在这种特殊情况下,您应该遵循 wilums2 的建议并扩展 MouseAdapter 而不是实现 MouseListener。这些适配器类的目的是让您在只实现接口的某些方法时不必提供空实现。

更一般地说,简短的回答是“不”,没有关于如何记录空方法的标准约定,尽管我通常使用类似的东西

@Override
void foo() {
  // No implementation necessary
}
于 2009-05-19T18:29:37.153 回答
9

我的做法和你一样,如果一条线上什么都没有。也许在一大堆“实施单线”之上发表评论。

于 2009-05-19T18:23:37.850 回答
5

一般来说,您所说的是空对象模式的扩展。您正在定义一个 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
于 2009-05-20T14:00:22.540 回答
5

使用鼠标适配器

于 2009-05-19T18:21:47.090 回答
2

有几种方法可以做到这一点。Oracle java 约定p6.4(第11 页)说空方法应该看起来像

public void empty() {}

还有一份史蒂夫·约哈南 ( Steve Yohanan ) 写于 2003 年 ant 的文件,上面写着

public void empty()
{
}

虽然我还没有找到“作为接口存根的空方法”的任何约定。因此,作为结论,没有标准化的方法来做到这一点。有些人喜欢留下评论,有些人喜欢让它成为单行,有些人喜欢用空白正文写成任何其他方法。

于 2014-01-10T11:59:37.710 回答
1

MouseAdapter 非常适合这种特定情况,而 Adapter 习惯用法通常也很棒。适配器具有接口的所有方法的空实现,允许您子类化并仅实现与您的类相关的那些方法。正如 Andrew Hare 建议的那样,适配器也可以抛出 NotImplementedException。

于 2009-05-19T18:26:33.617 回答
1

侦听器的目的是通知某些事件。如果侦听器接口包含的方法回调比您需要的多,那么只需忽略您不关心的那些。在您的情况下MouseAdapter,正是为此目的而设计的。不要抛出,因为UnsupportedOperationException调用者很可能不会期待异常。它也很可能违反了侦听器接口的约定,因为每个方法都需要实现。

于 2009-05-19T18:31:53.547 回答
0

我在搜索这个确切的问题时发现了这一点。我在需要 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;}

这个有很多参数,所以它看起来不像在一条线上那么好,但你明白了。

于 2012-08-25T14:06:26.160 回答
0

我想我会将其描述为“无操作实现”,或者使用“适配器”一词。正如其他人所指出的,Java 提供了一个MouseAdapter可以满足您需求的类。严格来说,它并不完全属于适配器模式的定义,它将一种 API 转换为另一种,但坦率地说,我倾向于务实地命名这些东西。

可能最重要的事情是明确您打算让该方法没有实现。在 的特定情况下MouseAdapter,您可能不想到处乱扔UnsupportedOperationException,但总的来说,这可能是一个很好的信号,表明您不打算提供实现。在源代码(或者更好的是方法文档)中的注释来解释为什么你没有完全实现接口通常是必要的。

于 2009-05-19T18:32:19.740 回答
0

我不认为这特别重要。就我个人的喜好而言,我不喜欢在开口旁边看到右大括号,它给出了:

public void mouseEntered(MouseEvent e) {
}

有点空,但还好。在返回值的情况下,我们可以使它看起来一致,这是您无法使用的[]样式。

但是当谈到循环中的罕见情况时,我喜欢其中的分号:

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

这会给:

public void mouseEntered(MouseEvent e) {
    ;
}

对于catch子句,您最好在评论中有一个很好的借口(也许放弃中断)。

于 2009-05-19T18:36:07.050 回答