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

时间:2009-02-27 13:39:59

标签: java interface inner-classes

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

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

11 个答案:

答案 0 :(得分:18)

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

./亚历

interface IEmployee
{

    void workHard ();  
    void procrastinate ();

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

}

另一个示例 - Null Object Pattern的实现:

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);
...

答案 1 :(得分:8)

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

无耻地从上述链接中扯下来:

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

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

答案 2 :(得分:6)

一个用途(无论好坏)将作为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);

答案 3 :(得分:5)

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

答案 4 :(得分:3)

这个成语被大量使用的地方是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有很大控制权的课程)并发现它相当干净。

答案 5 :(得分:2)

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

答案 6 :(得分:2)

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() {
            ...
        }
    }
}

答案 7 :(得分:2)

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

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);
}

答案 8 :(得分:1)

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

答案 9 :(得分:1)

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

答案 10 :(得分:1)

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