问题
I.e. why is the following "cyclic dependency" not possible?
public class Something implements Behavior {
public interface Behavior {
// ...
}
}
Since interfaces don't reference the outer class this should be allowed; however, the compiler is forcing me to define those interfaces outside the class. Is there any logical explanation for this behavior?
回答1:
Relevant rules in spec:
http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.1.4
A class C directly depends on a type T if T is mentioned in the extends or implements clause of C either as a superclass or superinterface, or as a qualifier of a superclass or superinterface name.
http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html#9.1.3
An interface I directly depends on a type T if T is mentioned in the extends clause of I either as a superinterface or as a qualifier within a superinterface name.
Therefore if A extends|implements B.C
, A depends on both C
and B
. Spec then forbids circular dependencies.
The motivation of including B
in the dependency is unclear. As you mentioned, if B.C
is promoted to top level C2
, not much is different as far as the type system is concerned, so why A extends C2
is ok, but not A extends B.C
? Granted a nested type B.C
does have some prviledged access to B
's content, but I can't find anything in spec that makes A extends B.C
troublesome.
The only problem is when C
is an inner class. Suppose B=A
, A extends A.C
should be forbidden, because there's a circular dependency of "enclosing instance". That is probably the real motivation - to forbid outer class from inheriting inner class. The actual rules are more generalized, because they are simpler, and make good sense anyway even for non-inner classes.
回答2:
Imagine you are the compiler.
We are saying you to create a class Something. This class implements Behavior... But Behavior does not exist yet because Something is not already registered...
Do you understand the problem ?
See class as box which contains things. Behavior is contained in the box Something. But Something does not exist.
回答3:
The simple fact that the language specs forbid it should be enough.
Some reasons I could think of:
It wouldn't be useful.
For whatever reasons you might want to use this, I'm sure there exist better options.
Child classes should extend base classes, so why would you declare a base class inside its own child?
It would be counter-intuitive having a separate class extend your inner-class.
来源:https://stackoverflow.com/questions/7993560/why-is-java-prohibiting-inheritance-of-inner-interfaces