【问题标题】:How should i implement an interface in Java? [Code-Correctness]我应该如何在 Java 中实现接口? [代码正确性]
【发布时间】:2014-08-25 22:00:25
【问题描述】:

首先,这不是关于如何在 Java 中实现接口的问题,也不是关于接口错误的问题。这是一个关于正确方法的问题,视情况而定。

首先,如果这不是发布此问题的正确“堆栈”,我想道歉,请告诉我,我会将其移至另一个。

让我们开始吧。

我想猜测的是,在 Java 中实现接口的最佳方式是哪一种。假设我们有一个 A 类:

public Class A {

    public A(){}
    public void fooA() {}
}

还有一个界面

public interface MyListener {
    public void fooListener();
}

在fooA()里面我是这样使用接口B的:

...
something.setFooListener(/**Doubts here**/)
....

我们应该在 setFooListener(...) 中输入什么

选项是(据我所知):

A) 定义 setFooListener 函数内部的行为:

new MyListener.fooListener() {
    /** Implementation of fooListener() **/
}

优点:

  • 在阅读函数时简单易读。

  • 您可以直接访问 fooA() 中定义的 FINAL 变量。

缺点:

  • 如果您的实现时间足够长,最终会导致缺乏可读性和函数过长。
  • 如果您在同一个类的几个地方实现接口,您将重复大量代码。

B) 创建实现接口的内部类:

private class MyListenerImplementation implements MyListener {
    private String var1;
    private int var2;

    public MyListenerImplementation() {/** constructor **/}

    public void fooListener() {
        /** Do logic here **/
    }
}

优点:

  • 您可以保留对对象 MyListenerImplementation 的引用。
  • 您可以定义变量、函数和一切,因为它是一个像任何其他对象一样的对象。
  • 更清洁的代码。

缺点:

  • 可能需要更多内存。
  • 可能会创建不必要的类

C) 持有一个引用接口实现的变量

private MyListener.FooListener myListenerVar = new MyListener.FooListener() {
    /** Logic goes here **/
};

优点:

  • 我实际上看不到任何人与 B 相比,但有很多缺点。

缺点:

  • 不是一个干净的代码。至少在课堂上这样做会构成战争罪。
  • 我认为将代码块分配给变量是不正确的。
  • 我不喜欢这个样子 ;)

D) 我能想到的最后一个;定义一个函数并在里面返回实现

private MyListener.fooListener createMyListener() {
    return new MyListener.fooListener() {
        /** Logic goes here **/
    }
}

优点:

  • 它比 C 更干净。
  • 可重用性

缺点:

  • 几乎和 C 一样。
  • 我认为返回整个代码块是不正确的。

总结:我最喜欢的是“B”,但我想知道SO对此有何看法。

感谢您的建议。

【问题讨论】:

  • 我很好奇,如果您对每个选项都有如此详细的优缺点列表,那么您在决定哪个选项最适合您时遇到问题呢?我怀疑是否有适合所有情况的答案。
  • 我错了还是错过了什么。我认为 A、C 和 D 不会编译。还是只是“伪”-Java?
  • @EdwinDalorzo 正如你所说,每个选项都有优点和缺点,我正在尝试找出哪个是最好的。下面的解决方案和你说的一样,没有单一的方法可以做到这一点,这取决于情况和你想要做什么、代码可重用性、类长度等......
  • @Fildor 实际上它没有经过测试 Java 代码,它应该可以编译,但也许它不会。 A) 在something.setFooListener() 的括号内。我相信 C 和 D 会编译,因为它只是一个变量,函数声明和语法是正确的,但也许我遗漏了一些东西。无论如何,这不是问题的重点。

标签: java oop interface correctness


【解决方案1】:

选项 A 在语法上不正确。你的优点和缺点都是有效的。

选项 B:

  • 可能需要更多内存:不。
  • 可能会创建不必要的类:不。选项 A 还创建一个类。它是匿名的,但它是一个类,必须像任何其他类一样由 ClassLoader 加载。

选项 C:它与 A 完全相同(匿名类用法),除了您使用侦听器初始化一个字段。规则与任何其他变量相同:尽可能缩小其范围。如果您需要字段范围,请使用此选项。如果您只需要一种方法中的侦听器,请使用局部变量(选项 A)。

选项 D:再次,它与 A 相同,只是您返回创建的侦听器而不是仅使用它。

我的回顾:您在这里混合了三个正交问题。

  1. 我应该使用匿名内部类、命名嵌套类还是顶级类。这取决于类中包含的代码量,以及您需要在何处使用此类:在单个顶级类中,还是在多个顶级类中。
  2. 我应该使用局部变量还是实例变量。这是范围和状态的问题,而不是接口实现的问题。您的字段或局部变量可以使用任何类型的接口实现的实例进行初始化
  3. 应该使用工厂方法返回实例,还是应该直接使用new。再一次,这与您的界面的实现方式无关。如果你想松耦合,因为工厂方法可能返回同一个接口的不同实现,使用工厂。否则,新的很好。

【讨论】:

  • 感谢您的回答,很抱歉花了这么多时间来回答您。因此,总而言之,没有更正确的方法可以做到这一点,所选择的选项将取决于我们目前需要什么。这实际上就是我现在面临这个问题的方式,这取决于我选择一种或另一种方式来做这些事情的情况;只是想知道是否有一种“总是必须使用”的方式来做到这一点。再次感谢您的回答
  • 你的方法是正确的。不要教条主义,根据情况选择最好的方式。
猜你喜欢
  • 2016-02-03
  • 2016-02-15
  • 1970-01-01
  • 2011-11-27
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-04
相关资源
最近更新 更多