为什么Java禁止inheritance内部接口?
即为什么以下“循环依赖”不可能?
public class Something implements Behavior { public interface Behavior { // ... } }
由于接口不引用外部类,因此应该允许; 但是,编译器迫使我在类外定义那些接口。 这种行为有合理的解释吗?
规范中的相关规则:
http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.1.4
如果在C的extends或implements子句中提到T作为超类或超接口,或者作为超类或超接口名称的限定符,则类C直接依赖于类型T.
http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html#9.1.3
如果在I的extends子句中提到T作为超接口或作为超接口名称中的限定符,则接口I直接依赖于类型T.
因此,如果A extends|implements BC
,则A依赖于C
和B
Spec然后禁止循环依赖。
将B
纳入依赖关系的动机尚不清楚。 正如你所提到的,如果将BC
提升到顶级C2
,就类型系统而言,并没有太大的不同,那么为什么A extends C2
是好的,但不是A extends BC
? 虽然嵌套类型BC
确实有一些对B
内容的访问权限,但我找不到任何规范使A extends BC
麻烦。
唯一的问题是当C
是内部类时。 假设B=A
,应该禁止A extends AC
,因为存在“封闭实例”的循环依赖性。 这可能是真正的动机 – 禁止外部阶级inheritance内部阶级。 实际的规则更加通用,因为它们更简单,并且即使对于非内部类也是很有意义的。
想象一下,你是编译器。
我们说你要创建一个类Something。 这个类实现了行为……但是行为还不存在,因为Something尚未注册…
你明白这个问题吗?
将class视为包含内容的框。 行为包含在Something框中。 但是某些东西不存在。
语言规范禁止它的简单事实就足够了。
我能想到的一些原因:
-
它没用。
-
无论出于何种原因,您可能想要使用它,我确信存在更好的选择。
-
子类应该扩展基类,那么为什么要在自己的子类中声明一个基类呢?
-
如果有一个单独的类扩展你的内部类,那将是违反直觉的。