【问题标题】:Why interface can only be declared in top-level class?为什么接口只能在顶级类中声明?
【发布时间】:2011-11-02 02:03:56
【问题描述】:

好吧,我知道这是规则:

根据 JLS:8.1.3 内部类和封闭实例,内部 类不能声明静态初始化器或成员接口。 内部类不能声明静态成员,除非它们是 编译时常量字段。

根据 8.5.2 静态成员类型声明,“成员接口 总是隐含的静态。允许但不是必需的 声明成员接口以显式列出静态 修饰符”。它们始终是顶级的,而不是内部的。

我只是想知道为什么。如果允许我们在内部类中声明接口会发生什么?如果我把它放到另一个Class文件中,内部类不会成为顶级类吗?

【问题讨论】:

    标签: java oop class interface inner-classes


    【解决方案1】:

    如果我把它放到另一个Class文件中,内部类不会成为顶级类吗?

    不,它仍然是一个内部类,文件名表明(IIRC 它是OuterClass$InnerClass.class)。

    内部类可以访问外部类的属性,即它们依赖于外部类的实例。使用接口您无法做到这一点。想想一个完全不相关的类,它必须由相应的外部类的实例创建。如果外部类不知道谁实现了那个接口怎么办?

    你可以做的是在你的外部类中声明静态接口,因此只使用外部类作为命名空间:

    public class OuterClass {
      public static interface InnerInterface { //protected and private would be fine too, depending on what makes sense
      }
    }
    

    编辑:实际上,我误读了这个问题,因为接口无论如何都是静态的,所以这里有一个更新的代码 sn-p:

     public class OuterClass {
      public static InnerClass { //static inner class making OuterClass just be a namespace
         public interface InnerInnerInterface { //protected and private would be fine too, depending on what makes sense
         }
      }
    }
    

    作为一种解决方法,您可以定义一个抽象的内部内部类,但缺点是您必须坚持单一继承约束。

    【讨论】:

    • 嗯,有趣!我从来不知道接口可以声明为静态的。这里的“静态”是什么意思?我试过用谷歌搜索静态界面,但没有发现任何东西。 P / s:只需在您引用的行编辑我的帖子,以纠正语法错误。
    • @W.N.:接口是隐式静态的。该声明只是多余的。
    • @Ryan 好点,我也只是重新阅读了这个问题,并会更新我的答案。
    【解决方案2】:

    从静态与非静态上下文的角度来考虑它。 “顶级”类建立了一个静态上下文,因为它可以在没有任何封闭实例的情况下访问。 IE。您可以从 main 方法访问顶级类。这同样适用于顶级类的任何静态成员。然而,内部类既不存在于*中,也不建立任何静态上下文。因此它不能有任何静态成员,并且只能通过其包含类的实例来访问,例如构造函数和其他实例成员。在 main 方法中,您不能说 Outer.Inner.SOME_FIELD,因为内部类的成员只对包含的类有意义。

    *有点

    【讨论】:

      【解决方案3】:

      根据定义,顶级类和它的内部类是紧密耦合的。接口是减少耦合的一种手段。

      【讨论】:

      • 即使我只需要为内部类私下使用该接口?
      • 这不一定是一个好的论据,因为我已经编写了许多只在单个类的范围内使用的私有嵌套接口。
      【解决方案4】:

      内部类应该是顶级类的实现细节,因此应该对客户端不可见。您希望访问内部类的任何功能都应该通过顶级类完成,因为从概念上讲,该功能应该仅作为顶级类的功能可见,以便类设计者可以换出或以其他方式在不破坏客户构建的情况下彻底改变内部类。

      【讨论】:

      • 这完全是见仁见智。如果内部类仅用于父类的内部使用,则不允许您将它们设为public
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-12
      • 2014-11-09
      • 2013-01-27
      • 2010-09-06
      • 1970-01-01
      • 2017-09-10
      相关资源
      最近更新 更多