109

是否可以在接口中创建内部类
如果可能,为什么我们要创建这样的内部类,因为我们不打算创建任何接口对象?

这些内部类在任何开发过程中都有帮助吗?

4

13 回答 13

115

是的,我们可以在接口内部拥有类。一个使用示例可能是

public interface Input
{
    public static class KeyEvent {
         public static final int KEY_DOWN = 0;
         public static final int KEY_UP = 1;
         public int type;
         public int keyCode;
         public char keyChar;
    }
    public static class TouchEvent {
         public static final int TOUCH_DOWN = 0;
         public static final int TOUCH_UP = 1;
         public static final int TOUCH_DRAGGED = 2;
         public int type;
         public int x, y;
         public int pointer;
    }
    public boolean isKeyPressed(int keyCode);
    public boolean isTouchDown(int pointer);
    public int getTouchX(int pointer);
    public int getTouchY(int pointer);
    public float getAccelX();
    public float getAccelY();
    public float getAccelZ();
    public List<KeyEvent> getKeyEvents();
    public List<TouchEvent> getTouchEvents();
}

这里的代码有两个嵌套类,它们用于封装有关事件对象的信息,这些信息稍后将用于方法定义,如 getKeyEvents()。将它们放在 Input 界面中可以提高凝聚力。

于 2013-12-10T12:41:52.937 回答
56

是的,您可以在 Java 接口中创建嵌套类或内部类(请注意,与流行的看法相反,没有“静态内部类”之类的东西:这根本没有意义,没有“内部”和“当嵌套类是静态的时,外部”类,因此它不能是“静态内部”)。

无论如何,以下编译得很好:

public interface A {
    class B {
    }
}

我曾经看到它曾经将某种“合同检查器”直接放在接口定义中(嗯,在嵌套在接口中的类中,可以有静态方法,与接口本身相反,它不能)。如果我没记错的话是这样的。

public interface A {
    static class B {
        public static boolean verifyState( A a ) {
            return (true if object implementing class A looks to be in a valid state)
        }
    }
}

请注意,我不是在评论这种东西的有用性,我只是在回答你的问题:它可以做到,这是我见过的一种用途。

现在我不会评论这种结构的有用性,而且我已经看到了:我已经看到了,但它不是一个非常常见的结构。

200KLOC 代码库在这里发生的时间恰好为零(但是我们还有很多其他的事情,我们认为这些不好的做法也恰好发生在零时间,其他人会觉得完全正常,所以......)。

于 2010-03-08T11:21:40.590 回答
48

恕我直言,有效的用途是定义由封闭接口方法接收或返回的对象。通常是数据保存结构。这样,如果该对象仅用于该接口,您就可以以一种更有凝聚力的方式拥有事物。

举例:

interface UserChecker {
   Ticket validateUser(Credentials credentials);

   class Credentials {
      // user and password
   }

   class Ticket {
      // some obscure implementation
   }
}

但无论如何......这只是一个品味问题。

于 2012-05-07T11:47:49.413 回答
42

引用Java 7 规范

接口可能包含成员类型声明(第 8.5 节)。

接口中的成员类型声明是隐式静态和公共的。允许冗余指定这些修饰符中的一个或两个。

不可能在 Java 接口中声明非静态类,这对我来说很有意义。

于 2014-10-16T11:41:33.167 回答
12

一个有趣的用例是通过内部类为接口方法提供某种默认实现,如下所述:https ://stackoverflow.com/a/3442218/454667 (以克服单类继承的问题)。

于 2013-02-13T10:43:17.763 回答
8

是的,在接口中可以有静态类定义,但也许这个特性最有用的方面是使用枚举类型(这是一种特殊的静态类)。例如你可以有这样的东西:

public interface User {
    public enum Role {
        ADMIN("administrator"),
        EDITOR("editor"),
        VANILLA("regular user");

        private String description;

        private Role(String description) {
            this.description = description;
        }

        public String getDescription() {
            return description;
        }
    }

    public String getName();
    public void setName(String name);
    public Role getRole();
    public void setRole(Role role);
    ...
}
于 2015-04-08T00:42:02.470 回答
8

这当然是可能的,我发现它很有用的一种情况是接口必须抛出自定义异常。您可以使用关联的接口保留异常,我认为这通常比在源代码树中堆放大量琐碎的异常文件更整洁。

interface MyInterface {

   public static class MyInterfaceException extends Exception {
   }

   void doSomething() throws MyInterfaceException;
}
于 2014-11-14T03:59:39.640 回答
1

@Bachi 提到的内容类似于 Scala 中的特征,实际上是使用接口内的嵌套类实现的。这可以在 Java 中模拟。另请参阅java 特征或 mixins 模式?

于 2013-05-02T12:48:54.013 回答
1

也许当您想要更复杂的结构(例如一些不同的实现行为)时,请考虑:

public interface A {
    public void foo();

    public static class B implements A {
        @Override
        public void foo() {
            System.out.println("B foo");
        }
    }
}

这是您的界面,这将是实现者:

public class C implements A {
    @Override
    public void foo() {
        A.B b = new A.B();
        b.foo(); 
    }

    public static void main(String[] strings) {
        C c = new C();
        c.foo();
    }
}

可能会提供一些静态实现,但不会令人困惑,我不知道。

于 2016-10-20T19:43:38.713 回答
0

You can also create "Helper" static classes for common functionality for the objects that implement this interface:

public interface A {
    static class Helper {
        public static void commonlyUsedMethod( A a ) {
           ...
        }
    }
}
于 2016-10-20T19:21:21.763 回答
0

我现在需要一个。我有一个接口,可以方便地从它的几个方法返回一个唯一的类。此类仅作为来自此接口的方法的响应的容器才有意义。

因此,有一个静态嵌套类定义会很方便,它只与这个接口相关联,因为这个接口应该是唯一创建这个结果容器类的地方。

于 2017-06-13T22:03:02.527 回答
0

我发现这种类型的构造很有用。

  1. 您可以使用此构造来定义和分组所有静态最终常量。
  2. 因为,它是一个接口,你可以在一个类上实现它。

您可以访问所有分组的常量;在这种情况下,类的名称充当命名空间。

于 2016-06-02T18:07:40.457 回答
0

例如Groovy 中的特征(类似于接口与实现的方法)。它们被编译成一个接口,该接口包含实现所有方法的内部类。

于 2017-06-13T22:10:06.983 回答