Interface中的内部类

问题描述 投票:82回答:13

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

这些内部类有助于任何开发过程吗?

java oop interface inner-classes
13个回答
42
投票

是的,您可以在Java界面中创建嵌套类或内部类(请注意,与流行的看法相反,没有“静态内部类”这样的东西:这根本没有意义,没有“内在”,没有“ outter“当​​一个嵌套类是静态的时,所以它不能是”静态内部“)。

无论如何,以下编译正常:

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代码库在这里恰好零时间发生(但后来我们还有许多其他的事情,我们认为不好的做法恰好发生在零时间,其他人会发现完全正常所以......)。


0
投票

我发现了这种结构的用途。

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

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


0
投票

您还可以为实现此接口的对象的常用功能创建“Helper”静态类:

public interface A {
    static class Helper {
        public static void commonlyUsedMethod( A a ) {
           ...
        }
    }
}

0
投票

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

因此,拥有静态嵌套类定义会很方便,该定义仅与此接口相关联,因为此接口应该是创建此结果容器类的唯一位置。


0
投票

例如,在Groovy中使用traits(类似于已实现方法的接口)。它们被编译为一个接口,该接口包含实现所有方法的内部类。


100
投票

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

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界面内可以提高内聚力。


40
投票

有效使用IMHO定义了封闭接口方法接收或返回的对象。数据保持结构。通过这种方式,如果对象仅用于该接口,那么您可以使用更具凝聚力的方式。

举例:

interface UserChecker {
   Ticket validateUser(Credentials credentials);

   class Credentials {
      // user and password
   }

   class Ticket {
      // some obscure implementation
   }
}

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


30
投票

引自Java 7 spec

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

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

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


10
投票

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


7
投票

它当然是可能的,并且我发现它有用的一种情况是接口必须抛出自定义异常。您可以使用相关的接口保留异常,我认为这些异常通常比使用大量异常文件乱丢源树更整洁。

interface MyInterface {

   public static class MyInterfaceException extends Exception {
   }

   void doSomething() throws MyInterfaceException;
}

7
投票

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

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

1
投票

@Bachi提到的内容类似于Scala中的特征,实际上是使用接口内的嵌套类实现的。这可以用Java模拟。另见java traits or mixins pattern?


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

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

© www.soinside.com 2019 - 2024. All rights reserved.