12

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

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

11 回答 11

18

除了 Eric P 链接的那些用法之外,我还可以想到另一种用法:定义接口的默认/无操作实现。

./亚历克斯

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);
...
于 2009-02-27T13:53:03.867 回答
8

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

无耻地从上面的链接中扯掉:

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

在上面的接口中,您将角色类型强绑定到员工接口(employee.Role)。

于 2009-02-27T13:45:30.793 回答
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);
于 2009-02-27T18:24:03.357 回答
5

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

于 2009-02-27T13:43:50.953 回答
3

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

通常,大多数 xml 模式类型都映射到 Java 接口。该接口内部有一个工厂,用于在默认实现中生成该接口的实例:

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 绑定到接口定义中似乎是错误的。然而,我实际上越来越喜欢它,因为它让一切都根据接口定义,但有一个统一的方式来获取接口的实例(而不是有另一个外部工厂/构建器类)。

我将它用于有意义的类(尤其是那些我对接口/实现有很大控制权的类),并发现它相当干净。

于 2009-03-01T08:02:53.660 回答
2

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

于 2009-02-27T13:46:14.990 回答
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() {
            ...
        }
    }
}
于 2009-02-27T14:20:04.220 回答
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);
}
于 2009-03-01T23:14:33.123 回答
1

这样做似乎到处都写着“糟糕的设计决策”。

于 2009-02-27T13:48:28.947 回答
1

每当创建非私有嵌套类似乎是个好主意时,我都会敦促谨慎。几乎可以肯定,您最好直接参加外部课程。但是如果你要创建一个公共的嵌套类,把它放在一个接口中似乎并不比放在一个类中更奇怪。外部类的抽象性不一定与嵌套类的抽象性相关。

于 2009-02-27T14:16:23.387 回答
1

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

于 2009-03-01T08:29:25.560 回答