Cyclic inheritance and interfaces - class A can't implement class B interface while class B implements A interface

前端 未结 2 557
醉梦人生
醉梦人生 2020-12-18 06:27

I have:

public class A implements BListener {
    public interface AListener {}
}

public class B implements AListener {
    public interface BListener {}
}
         


        
相关标签:
2条回答
  • 2020-12-18 06:52

    After further investigation, I was initially wrong.

    The technical explanation for the behavior you are noticing is the following

    From the Java Language Specification chapter on Superclasses and subclasses

    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 in the fully qualified form of a superclass or superinterface name.

    A class C depends on a reference type T if any of the following is true:

    • C directly depends on T.
    • C directly depends on an interface I that depends (§9.1.3) on T.
    • C directly depends on a class D that depends on T (using this definition recursively).

    It is a compile-time error if a class depends on itself.

    Let's take your code, with fully qualified names for type uses, assuming the classes were declared in package com.example:

    public class A implements com.example.B.BListener {
        public interface AListener {}
    }
    
    public class B implements com.example.A.AListener {
        public interface BListener {}
    }
    

    Following the rules from the JLS above

    • A directly depends on BListener, because it's mentioned in its implements clause.
    • A directly depends on B, because it's mentioned as a qualifier in the fully qualified name of a superinterface (BListener is com.example.B.BListener)
    • B directly depends on AListener, because it's mentioned in its implements clause.
    • B directly depends on A, because it's mentioned as a qualifier in the fully qualified name of a superinterface (AListener is com.example.A.AListener)
    • A directly depends on B that depends on A.

    Therefore A depends on A and a compilation error should occur.


    In Eclipse, the error occurs if you qualify the names

    class A implements B.BListener {
        public static interface AListener {
        }
    }
    
    class B implements A.AListener {
        public static interface BListener {
        }
    }
    

    If you use import statements, however, it doesn't. I'll be opening a bug with them.

    0 讨论(0)
  • 2020-12-18 06:55

    It may help to draw it out.

                  >A 
    is part of  /     \    inherits
                       V             
       AListener        BListener
               ^
      inherits  \     /    is part of 
                   B<
    

    A lovely circle. You can't create one of them without the others already existing.

    Is the compiler a squirrel with ADHD high on coffee chasing it's own tail?

    Nope because a the squirrel would not stop (until the caffeine ran out). The compiler looks for this and then gives up.

    Note: Eclipse has a bug which allows this setup.

    0 讨论(0)
提交回复
热议问题