2011-08-23 73 views
10

好吧,我知道它的规则:为什么只能在顶级类中声明接口?

根据JLS:8.1.3内部类和内附的情况下,内部 类可以不声明静态初始化或成员接口。 内部类可能不会声明静态成员,除非它们是编译时常量字段 。

根据8.5.2静态成员类型声明,“会员接口 总是静态的,它是允许的,但不是必需的 声明成员接口明确列出静态 修改”。他们永远是顶级的,而不是内在的。

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

回答

7

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

不,它仍然是一个内部类,其文件名表示(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 
    } 
    } 
} 

正如你可以定义一个抽象里面的内类,与你必须坚持到单继承约束的缺点,一种解决方法。

+0

嗯,有趣!我永远不知道该接口可以声明为静态的。这里“静态”是什么意思?我试过谷歌静态界面,但没有发现任何东西。 P/s:只需在您引用的行编辑我的帖子,以纠正语法错误。 –

+2

@ W.N .:接口是隐式静态的。该声明只是减少。 –

+1

@Ryan好点,我也只是重读这个问题,并会更新我的答案。 – Thomas

1

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

+2

这都是意见。如果内部类仅用于父类的内部使用,则不允许将它们设置为“公共”。 – skaffman

2

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

+1

即使我只需要为内部类私下使用该接口? –

+0

这不一定是一个好的参数,因为我已经编写了一些私有的嵌套接口,这些接口仅在单个类的范围内使用。 –

4

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

*种类

+0

这个答案会让托马斯的答案更清晰。 +1。 –

相关问题