Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top