在Java中用接口定义类的能力的实用方面?

在Java中用接口定义类的能力的实际方面是什么:

interface IFoo { class Bar { void foobar () { System.out.println("foobaring..."); } } } 

我可以想到另一种用法,而不是Eric P链接的用法:定义接口的默认/无操作实现。

./alex

 interface IEmployee { void workHard (); void procrastinate (); class DefaultEmployee implements IEmployee { void workHard () { procrastinate(); }; void procrastinate () {}; } } 

又一个示例 – 空对象模式的实现 :

 interface IFoo { void doFoo(); IFoo NULL_FOO = new NullFoo(); final class NullFoo implements IFoo { public void doFoo () {}; private NullFoo () {}; } } ... IFoo foo = IFoo.NULL_FOO; ... bar.addFooListener (foo); ... 

我认为这个页面很好地解释了一个例子。 您可以使用它将某种类型紧密绑定到接口。

从上面的链接无耻地撕掉:

 interface employee{ class Role{ public String rolename; public int roleId; } Role getRole(); // other methods } 

在上面的界面中,您将Role类型强烈绑定到employee接口(employee.Role)。

一个用途(无论好坏)将作为Java不支持接口中的静态方法这一事实的解决方法。

 interface Foo { int[] getData(); class _ { static int sum(Foo foo) { int sum = 0; for(int i: foo.getData()) { sum += i; } return sum; } } } 

然后你打电话给:

 int sum = Foo._.sum(myFoo); 

我可以毫不犹豫地说,我从来没有这样做过。 我想不出你为什么会这样做的原因。 嵌套在类中的类? 当然,有很多理由这样做。 在这些情况下,我倾向于将这些内部类视为实现细节。 显然,接口没有实现细节。

这个成语被大量使用的地方是XMLBeans 。 该项目的目的是采用XML Schema并生成一组Java类,您可以双向使用这些Java类来处理与模式相对应的XML文档。 因此,它允许您将XML解析为xml bean或创建xml bean并输出到xml。

通常,大多数xml架构类型都映射到Java接口。 该接口在其中包含一个Factory,用于在默认实现中生成该接口的实例:

 public interface Foo extends XmlObject { public boolean getBar(); public boolean isSetBar(); public void setBar(boolean bar); public static final SchemaType type = ... public static final class Factory { public static Foo newInstance() { return (Foo)XmlBeans.getContextTypeLoader().newInstance(Foo.type, null); } // other factory and parsing methods } } 

当我第一次遇到这个时,将所有这个实现gunk绑定到接口定义似乎是错误的。 然而,我实际上喜欢它,因为它让所有东西都根据接口定义,但是有一个统一的方法来获取接口的实例(而不是拥有另一个外部工厂/构建器类)。

我选择了那些有意义的课程(尤其是那些我对界面/ impls有很大控制权的课程)并发现它相当干净。

我猜你可以定义一个类,用作接口中方法的返回类型或参数类型。 似乎没有特别有用。 您也可以单独定义该类。 唯一可能的优点是它在某种意义上将类声明为“属于”接口。

Google Web Toolkit使用此类将“普通”接口绑定到异步调用接口:

 public interface LoginService extends RemoteService { /** * Utility/Convenience class. * Use LoginService.App.getInstance() to access static instance of LoginServiceAsync */ class App { public static synchronized LoginServiceAsync getInstance() { ... } } } 

通过接口内部的静态类,您可以缩短公共编程片段:检查对象是否是接口的实例,如果是,则调用此接口的方法。 看看这个例子:

 public interface Printable { void print(); public static class Caller { public static void print(Object mightBePrintable) { if (mightBePrintable instanceof Printable) { ((Printable) mightBePrintable).print(); } } } } 

而不是这样做:

 void genericPrintMethod(Object obj) { if (obj instanceof Printable) { ((Printable) obj).print(); } } 

你可以写:

 void genericPrintMethod(Object obj) { Printable.Caller.print(obj); } 

这样做似乎已经写了“糟糕的设计决定”。

每当创建一个非私有嵌套类似乎是个好主意时,我会小心谨慎。 你几乎肯定会更好地直接去外地。 但是如果你要创建一个公共嵌套类,那么把它放在接口而不是类中似乎没什么奇怪的。 外部类的抽象性不一定与嵌套类的抽象性相关。

此方法可用于在同一文件中定义许多类。 在过去我有很多简单的接口实现,这对我来说效果很好。 但是,如果我再次这样做,我会使用一个实现接口的枚举,这将是一个更优雅的解决方案。