简体   繁体   English

接口内的内部类

[英]Inner class within Interface

Is it possible to create an inner class within an interface?是否可以在接口中创建内部类
If it is possible why would we want to create an inner class like that since we are not going to create any interface objects?如果可能的话,我们为什么要创建这样的内部类,因为我们不打算创建任何接口对象?

Do these inner classes help in any development process?这些内部类对任何开发过程有帮助吗?

Yes, we can have classes inside interfaces.是的,我们可以在接口中使用类。 One example of usage could be使用的一个例子可能是

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

Here the code has two nested classes which are for encapsulating information about event objects which are later used in method definitions like getKeyEvents().这里的代码有两个嵌套的类,它们用于封装有关事件对象的信息,这些信息稍后用于方法定义,如 getKeyEvents()。 Having them inside the Input interface improves cohesion.将它们放在 Input 界面中可以提高凝聚力。

Yes, you can create both a nested class or an inner class inside a Java interface (note that contrarily to popular belief there's no such thing as an " static inner class ": this simply makes no sense, there's nothing "inner" and no "outter" class when a nested class is static, so it cannot be "static inner").是的,您可以在 Java 接口中创建嵌套类或内部类(请注意,与流行的看法相反,没有“静态内部类”这样的东西:这根本没有意义,没有“内部”和“当嵌套类是静态的时,外部”类,因此它不能是“静态内部”)。

Anyway, the following compiles fine:无论如何,以下编译正常:

public interface A {
    class B {
    }
}

I've seen it used to put some kind of "contract checker" directly in the interface definition (well, in the class nested in the interface, that can have static methods, contrarily to the interface itself, which can't).我已经看到它曾经将某种“合同检查器”直接放在接口定义中(好吧,在嵌套在接口中的类中,它可以具有静态方法,而接口本身则不能)。 Looking like this if I recall correctly.如果我没记错的话,看起来像这样。

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

Note that I'm not commenting on the usefulness of such a thing, I'm simply answering your question: it can be done and this is one kind of use I've seen made of it.请注意,我不是在评论这种东西的用处,我只是在回答你的问题:它可以做到,这是我见过的一种用途。

Now I won't comment on the usefulness of such a construct and from I've seen: I've seen it, but it's not a very common construct.现在我不会评论这样一个构造的有用性,并且从我所看到的:我已经看到了它,但它不是一个非常常见的构造。

200KLOC codebase here where this happens exactly zero time (but then we've got a lot of other things that we consider bad practices that happen exactly zero time too that other people would find perfectly normal so...). 200KLOC 代码库在这里发生的时间恰好为零(但是我们还有很多其他事情,我们认为这些错误的做法也恰好在零时间发生,而其他人会认为这是完全正常的……)。

A valid use, IMHO, is defining objects that are received or returned by the enclosing interface methods.一个有效的用法,恕我直言,是定义由封闭接口方法接收或返回的对象。 Tipically data holding structures.通常是数据保存结构。 In that way, if the object is only used for that interface, you have things in a more cohesive way.这样,如果该对象仅用于该接口,那么您就可以以更具凝聚力的方式拥有事物。

By example:举例:

interface UserChecker {
   Ticket validateUser(Credentials credentials);

   class Credentials {
      // user and password
   }

   class Ticket {
      // some obscure implementation
   }
}

But anyway... it's only a matter of taste.但无论如何……这只是品味问题。

Quote from the Java 7 spec :引用自Java 7 规范

Interfaces may contain member type declarations (§8.5).接口可能包含成员类型声明(第 8.5 节)。

A member type declaration in an interface is implicitly static and public.接口中的成员类型声明是隐式静态和公共的。 It is permitted to redundantly specify either or both of these modifiers.允许冗余指定这些修饰符中的一个或两个。

It is NOT possible to declare non-static classes inside a Java interface, which makes sense to me.不可能在 Java 接口中声明非静态类,这对我来说很有意义。

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

It certainly is possible, and one case where I've found it useful is when an interface has to throw custom exceptions.这当然是可能的,我发现它很有用的一种情况是接口必须抛出自定义异常。 You the keep the exceptions with their associated interface, which I think is often neater than littering your source tree with heaps of trivial exception files.您可以将异常与其关联的接口一起保留,我认为这通常比用一堆琐碎的异常文件乱扔您的源树更整洁。

interface MyInterface {

   public static class MyInterfaceException extends Exception {
   }

   void doSomething() throws MyInterfaceException;
}

Yes it is possible to have static class definitions inside an interface, but maybe the most useful aspect of this feature is when using enum types (which are special kind of static classes).是的,在接口中可以有静态类定义,但这个特性最有用的方面可能是使用枚举类型(这是一种特殊的静态类)。 For example you can have something like this:例如,你可以有这样的东西:

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

What @Bachi mentions is similar to traits in Scala and are actually implemented using a nested class inside an interface. @Bachi 提到的类似于 Scala 中的特征,实际上是使用接口内的嵌套类实现的。 This can be simulated in Java.这可以在 Java 中模拟。 See also java traits or mixins pattern?另请参阅java 特性或 mixins 模式?

Maybe when you want more complex constructions like some different implementation behaviours, consider:也许当您想要更复杂的结构(例如一些不同的实现行为)时,请考虑:

public interface A {
    public void foo();

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

This is your interface and this will be the implementee:这是您的界面,这将是实施者:

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

May provide some static implementations, but won't that be confusing, I don't know.可能会提供一些静态实现,但这不会令人困惑,我不知道。

I found a use fir this type of construct.我发现了这种类型的构造的用途。

  1. You can use this construct to defines and group all the static final constants.您可以使用此构造来定义和分组所有静态最终常量。
  2. Since, it is an interface you can implement this on an class.因为,它是一个接口,您可以在类上实现它。

You have access to all the constants grouped;您可以访问所有分组的常量; name of the class acts as a namespace in this case.在这种情况下,类的名称充当命名空间。

You can also create "Helper" static classes for common functionality for the objects that implement this interface:您还可以为实现此接口的对象的通用功能创建“Helper”静态类:

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

I'm needing one right now.我现在需要一个。 I have an interface where it would be convenient to return a unique class from several of it's methods.我有一个接口,可以方便地从它的几个方法返回一个唯一的类。 This class only makes sense as a container for responses from methods of this interface.此类仅作为来自此接口方法的响应的容器才有意义。

Hence, it would be convenient to have a static nested class definition, which is associated only with this interface, since this interface should be the only place where this results container class is ever created.因此,有一个静态嵌套类定义会很方便,它只与这个接口相关联,因为这个接口应该是唯一创建这个结果容器类的地方。

For instance traits (smth like interface with implemented methods) in Groovy.例如,Groovy 中的特性(类似于具有已实现方法的接口)。 They are compiled to an interface which contains inner class where all methods are implemented.它们被编译为一个接口,其中包含实现所有方法的内部类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM