为什么界面只能在顶级类中声明?

时间:2011-08-23 15:43:23

标签: java oop class interface inner-classes

好吧,我知道这是规则:

  

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

     

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

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

4 个答案:

答案 0 :(得分:7)

  

如果我将内部类放入另一个类文件中,内部类是否会成为顶级类?

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

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

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

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

编辑:实际上,我误解了这个问题,因为接口是静态的,这里是一个更新的代码片段:

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

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

答案 1 :(得分:4)

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

*有点

答案 2 :(得分:2)

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

答案 3 :(得分:1)

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