在接口中嵌套一个类是个好主意吗?

3
在Java中,是否可能在接口内部有一个内部类?

1
请澄清一下,您想知道是否可能还是是否明智? - Steve Kuo
7个回答

3

你可以这样做。但这是O'Reilly对此的说法:

接口中的嵌套类?

Java支持在接口中定义嵌套类,其语法和动态特性与在类中声明的嵌套类相同。然而,在接口内部声明一个类将是极其糟糕的编程实践。接口是概念的抽象,而不是实现。因此,实现细节应该留在接口之外。记住,仅仅因为你可以用锯子砍掉你的手并不意味着这是一个特别好的想法。


话虽如此,我可以理解一个静态实用工具类嵌套到一个接口中的论点。尽管为什么它需要嵌套到接口中而不是作为独立的类完全是主观的。


1
我不同意。一个复杂的“引用”接口可以使用简单的值类。话虽如此,我不喜欢公共静态嵌套类。 - Tom Hawtin - tackline
有时候接口只是为了其他原因而存在,有些人过度使用接口,每个接口只有一个实现。我认为将其混合使用是一个很酷的想法。 - IAdapter
我基本上同意应该小心处理这个问题,不要通过嵌套类来将接口与特定实现绑定。但是,如果嵌套类具有仅使用通用接口的功能,并且是针对该接口而不是其他功能的特定功能,那么我就没有反对意见。换句话说,只要接口仍然可以在其他地方重复使用而不修改内部类,那就没问题了。 - jdmichal

2

我同意这应该是一种普遍很少用到的方式,但是当接口方法需要返回多个信息时,我喜欢在服务中使用内部类,因为它确实是契约的一部分而不是实现。例如:

public interface ComplexOperationService {

    ComplexOperationResponse doComplexOperation( String param1, Object param2 );

    public static class ComplexOperationResponse {
        public int completionCode;
        public String completionMessage;
        public List<Object> data;
        // Or use private members & getters if you like...
    }

}

很明显这也可以在一个单独的类中完成,但是对我来说,感觉把整个接口定义的API放在一个地方比分散更好。

1

是的,这是可能的,但这不是常见的做法。

interface Test
{
    class Inner
    { }
}

class TestImpl implements Test
{
    public static void main(String[] arg)
    {
        Inner inner = new Inner();
    }
}

1

虽然没有直接回答你的问题,但是在相关的话题上,你也可以将一个接口嵌套在另一个接口中。这是可以接受的,特别是如果你想提供视图。例如,Java的集合类就是这样做的,比如Map.java中的Map.Entry视图:

public interface Map<K,V> {
   ...
   public static interface Entry<K,V> {
       ....
   }
}

这是可以接受的,因为您没有将实现细节混合到接口中。您只是指定了另一个契约。


我也使用这种技术来为另一个接口指定回调接口。非常方便。 - jdmichal
它为什么不在另一个类中? - Eaton Emmerich
@EatonEmmerich 你需要问设计集合API的Joshua Bloch。我猜 Entry<K, V> 接口在 Map<K, V> 之外并不实用,只有在 Map<K, V> 中使用(因为它是地图的视图)。我可以看到定义一个通用的 KeyValuePair<K, V> 接口,但可能会被滥用来保存两个不一定相关的任意值,所以也许这就是将其范围限定在 Map<K, V> 接口中的原因。 - Vivin Paliath

0

这是合法的,但我只在嵌套接口(如前所述)或嵌套枚举中使用它。例如:

public interface MyInterface {

    public enum Type { ONE, TWO, THREE }

    public Type getType();

    public enum Status { GOOD, BAD, UNKNOWN }

    public Status getStatus();

}

0

是的。直接来自语言规范

内部类是一个嵌套类,它没有明确或隐式地声明为static

并且(我加粗):

嵌套类是任何在另一个类或接口的主体中声明的类。


0

我发现这个非常有用的一种情况是,如果您有一个创建接口实例的构建器。如果构建器是接口的静态成员,则可以像这样创建一个实例:

DigitalObject o = new DigitalObject.Builder(content).title(name).build();

那将是接口实现的一个实例。我认为这不是一个好主意。 - Tom Hawtin - tackline
@Tom 是的,一个符合接口的实例,但具体类可以保持包私有并完全隐藏在API后面,因为构建器返回类型是接口。在我看来,这指定了一个接口以及一种创建实例的方法,而不会透露任何具体的实现。与将构建器作为顶级类型相比,我没有看到任何不利之处。 - Fabian Steeg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接