【问题标题】:Inner class within Interface接口内的内部类
【发布时间】:2011-01-24 22:37:11
【问题描述】:

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

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

【问题讨论】:

    标签: java oop interface inner-classes


    【解决方案1】:

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

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

    【讨论】:

    • @Levit 只是想知道,实现的类会是什么样子?
    • 希望看到上述用法的实际实现。谢谢。
    【解决方案2】:

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

    【讨论】:

    • 您能添加一些使用示例吗?我前段时间测试过类似的东西,但不明白使用这种结构能得到什么。
    • @Roman:好吧,我记得我在某个项目中遇到过这个问题(我会添加相对干净的项目,但它们不是我的),但我不知道它是否真的很干净。我添加了一个看起来像我所看到的小例子,但又一次:这不是我的代码,我没有使用那个结构,所以我不是最有资格提出有效例子的人:) IIRC里面的类总是被命名,例如 StateChecker 并且调用总是看起来像:A.StateChecker.check(a) 或类似的东西。
    • 如果你说“没有“静态内部类”这样的东西””你的答案是“你可以创建一个嵌套类或 Java 接口中的内部类”是根本错误的。使用您的缩小定义,interfaces 可以没有有内部类。您可以省略 interface 的嵌套类的 static 修饰符,但它仍然是嵌套类,而不是内部类。
    • 这个答案是错误的。接口可以有静态嵌套类,但不能有内部类。
    • @PaulBoddington 你是对的。即使删除“静态”,B 类也是静态嵌套类而不是内部类;接口得到特殊处理。除了规范本身之外,我在网上找不到提及这一点:“接口的成员类是隐式静态的,因此永远不会被视为内部类。” docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.3
    【解决方案3】:

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

    举例:

    interface UserChecker {
       Ticket validateUser(Credentials credentials);
    
       class Credentials {
          // user and password
       }
    
       class Ticket {
          // some obscure implementation
       }
    }
    

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

    【讨论】:

      【解决方案4】:

      引用自Java 7 spec

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

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

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

      【讨论】:

      • 谢谢。这可能是最简洁的答案。
      • 这是我一直在寻找的答案.. 但是 OP 提出了几个问题.. 无论如何都有我的 updoot。
      【解决方案5】:

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

      【讨论】:

      • 这正是私有成员类有意义的原因。
      【解决方案6】:

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

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

        【讨论】:

          【解决方案8】:

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

          【讨论】:

            【解决方案9】:

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

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

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

            【讨论】:

              【解决方案10】:

              我发现这种结构的用途。

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

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

              【讨论】:

                【解决方案11】:

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

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

                【讨论】:

                  【解决方案12】:

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

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

                  【讨论】:

                    【解决方案13】:

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

                    【讨论】:

                      猜你喜欢
                      • 2011-12-03
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2019-12-21
                      相关资源
                      最近更新 更多