即。为什么以下“循环依赖”不可能?
public class Something implements Behavior {
public interface Behavior {
// ...
}
}
由于接口不引用外部类,因此应该允许;但是,编译器迫使我在类外定义那些接口。这种行为有合理的解释吗?
答案 0 :(得分:11)
规范中的相关规则:
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直接依赖于类型T,如果在I的extends子句中提到T作为超接口或超接口名称中的限定符。
因此,如果A extends|implements B.C
,A取决于C
和B
。 Spec然后禁止循环依赖。
将B
纳入依赖关系的动机尚不清楚。正如您所提到的,如果将B.C
提升为顶级C2
,那么就类型系统而言,并不是很多,那么为什么A extends C2
没问题,而不是A extends B.C
}?虽然嵌套类型B.C
确实拥有对B
内容的一些简单访问权限,但我找不到任何使A extends B.C
麻烦的规范。
唯一的问题是C
是一个内部类。假设B=A
,A extends A.C
应该被禁止,因为“封闭实例”存在循环依赖关系。这可能是真正的动机 - 禁止外部类继承内部类。实际的规则更加通用,因为它们更简单,即使对于非内部类也是很有道理的。
答案 1 :(得分:10)
想象一下你是编译器。
我们说你要创建一个类Something。 这个类实现了行为...... 但是行为尚不存在,因为某些东西尚未注册......
你明白这个问题吗?
将class视为包含内容的框。行为包含在Something框中。但是某些东西不存在。
答案 2 :(得分:0)
语言规范禁止它的简单事实就足够了。
我能想到的一些原因:
没用。
无论出于何种原因,您可能都希望使用此功能,我确信有更好的选择。
子类应该扩展基类,那么为什么要在自己的子类中声明一个基类呢?
如果有一个单独的类扩展你的内部类,那将是违反直觉的。