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

发布于 2024-07-14 03:10:38 字数 195 浏览 6 评论 0原文

在 Java 中在接口中定义类的能力有什么实际意义:

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

What would be the practical side of the ability to define a class within an interface in Java:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

起风了 2024-07-21 03:10:38

我可以想到 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);
...

I can think of another usage than those linked by Eric P: defining a default/no-op implementation of the interface.

./alex

interface IEmployee
{

    void workHard ();  
    void procrastinate ();

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

}

Yet another sample — implementation of 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);
...
隐诗 2024-07-21 03:10:38

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

无耻地从上面的链接中窃取:

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

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

I think this page explains one example pretty well. You would use it to tightly bind a certain type to an interface.

Shamelessly ripped off from the above link:

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

In the above interface you are binding the Role type strongly to the employee interface(employee.Role).

凉城已无爱 2024-07-21 03:10:38

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

One use (for better or worse) would be as a workaround for the fact that Java doesn't support static methods in interfaces.

interface Foo {
    int[] getData();

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

Then you'd call it with:

int sum = Foo._.sum(myFoo);
桃扇骨 2024-07-21 03:10:38

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

I can say without hesitation that I've never done that. I can't think of a reason why you would either. Classes nested within classes? Sure, lots of reasons to do that. In those cases I tend to consider those inner classes to be an implementation detail. Obviously an interface has no implementation details.

绿光 2024-07-21 03:10:38

这一习惯用法大量使用的地方是 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
  }
} 

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

我为那些有意义的类(特别是那些我对接口/实现有很大控制权的类)选择了它,并发现它相当干净。

One place this idiom is used heavily is in XMLBeans. The purpose of that project is to take an XML Schema and generate a set of Java classes that you can use bidirectionally to work with XML documents corresponding to the schema. So, it lets you parse XML into xml beans or create the xml beans and output to xml.

In general, most of the xml schema types are mapped to a Java interface. That interface has within it a Factory that is used to generate instances of that interface in the default implementation:

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

When I first encountered this it seemed wrong to bind all this implementation gunk into the interface definition. However, I actually grew to like it as it let everything get defined in terms of interfaces but have a uniform way to get instances of the interface (as opposed to having another external factory / builder class).

I picked it up for classes where this made sense (particularly those where I had a great deal of control over the interface/impls) and found it to be fairly clean.

谁与争疯 2024-07-21 03:10:38

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

I guess you could define a class that is used as the return type or parameter type for methods within the interface. Doesn't seem particularly useful. You might as well just define the class separately. The only possible advantage is that it declares the class as "belonging" to the interface in some sense.

橪书 2024-07-21 03:10:38

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

Google Web Toolkit uses such classes to bind 'normal' interface to asynchronous call interface:

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() {
            ...
        }
    }
}
黎夕旧梦 2024-07-21 03:10:38

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

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

With a static class inside an interface you have the possibility to shorten a common programming fragment: Checking if an object is an instance of an interface, and if so calling a method of this interface. Look at this example:

public interface Printable {
    void print();

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

Now instead of doing this:

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

You can write:

void genericPrintMethod(Object obj) {
   Printable.Caller.print(obj);
}
ま昔日黯然 2024-07-21 03:10:38

这样做似乎写满了“糟糕的设计决策”。

Doing this seems to have "Bad design decision" written all over it.

指尖凝香 2024-07-21 03:10:38

每当创建非私有嵌套类看起来是个好主意时,我都会敦促您谨慎行事。 几乎可以肯定,直接进入外部班级会更好。 但是,如果您要创建一个公共嵌套类,那么将其放在接口中似乎并不比放在类中更奇怪。 外部类的抽象性与嵌套类的抽象性不一定相关。

I would urge caution whenever it seems like a good idea to create a non-private nested class. You are almost certainly better off going straight for an outer class. But if you are going to create a public nested class, it doesn't seem any more strange to put it in an interface than a class. The abstractness of the outer class is not necessarily related to the abstractness of a nested class.

奢望 2024-07-21 03:10:38

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

This approach can be used to define many classes in the same file. This has worked well for me in the past where I have many simple implementations of an interface. However, if I were to do this again, I would use an enum which implements an interface which would have been a more elegant solution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文