循环继承和接口 - 当类B实现A接口时,类A无法实现类B接口

5

我有:

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

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

所以,如果我理解正确,循环继承是因为:

编译器去找A并说:“嘿,A实现了BListener,让我们去找BListener!”

然后当它尝试找到BListener时,最终会到达B,而它会说:

“嘿,A需要的BListener在B内!但等等,B也需要AListener!让我们去找AListener!”

接着就回到了A,如此反复。我理解得对吗?

顺便说一下,我在Android开发中遇到了这个编译错误。


为什么这个问题会被评为负分? - Not Gabriel
这是什么?你遇到了编译错误吗?是哪个编译错误? - Sotirios Delimanolis
2个回答

6
可能画出来会有所帮助。
              >A 
is part of  /     \    inherits
                   V             
   AListener        BListener
           ^
  inherits  \     /    is part of 
               B<

一个可爱的圆圈。你不能在其他元素不存在的情况下创建其中的任何一个。

编译器是一只高速奔跑,追逐自己尾巴的咖啡因过度兴奋的松鼠吗?

不,因为一只松鼠不会停止(直到咖啡因耗尽)。编译器会查找这个,然后放弃。

注意:Eclipse存在一个允许此设置的错误。


这是一只非常有决心的松鼠!谢谢,那我理解得没错。7分钟后接受。 - Not Gabriel
关于编程的内容翻译:re "is part of"; 接口不应该是静态的吗? - Pacerier

2
经过进一步调查,我最初是错误的。
您注意到的行为的技术解释如下:
来自Java语言规范中超类和子类章节。
一个类 C 直接依赖于类型 T,如果 TCextendsimplements 子句中被提及,可以是作为超类或超级接口,也可以是在超类或超级接口名称的完全限定形式中作为限定符。
一个类 C 依赖于引用类型 T,如果以下任一条件成立:
- C 直接依赖于 T。 - C 直接依赖于依赖(§9.1.3)于 T 的接口 I。 - C 直接依赖于依赖于 T 的类 D(使用此定义递归)。
如果一个类依赖于自身,则会导致编译时错误。
假设这些类是在包 com.example 中声明的,我们来看看你的代码,使用了类型使用的完全限定名。
public class A implements com.example.B.BListener {
    public interface AListener {}
}

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

根据JLS中的规则:
  • A 直接依赖于 BListener,因为它在其implements子句中被提及。
  • A 直接依赖于 B,因为它作为超级接口的完全限定名称中的限定符被提及(BListenercom.example.B.BListener
  • B 直接依赖于 AListener,因为它在其implements子句中被提及。
  • B 直接依赖于 A,因为它作为超级接口的完全限定名称中的限定符被提及(AListenercom.example.A.AListener
  • A 直接依赖于依赖于 AB
因此,A 依赖于 A,应该出现编译错误。
在 Eclipse 中,如果您限定名称,就会发生错误。
class A implements B.BListener {
    public static interface AListener {
    }
}

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

如果您使用import语句,它就不会出现这种情况。我将向他们提交一个错误报告。

在Maven中,[ERROR] /home/mlk/code/test_project/src/test/java/com/example/A.java:[4,7] error: cyclic inheritance involving A - Michael Lloyd Lee mlk
@mlk 8,但我认为那不重要。据我所知,这个过程没有改变。 - Sotirios Delimanolis
@mlk 是的,看起来编译器的行为有所不同。 (https://dev59.com/Ll_Va4cB1Zd3GeqPTnYZ) - Sotirios Delimanolis
我正在使用AndroidStudio。只要我完成代码编写,它就会发出抱怨声。 - Not Gabriel
1
@mlk 经过调查JLS,这是Eclipse中的一个bug。在“implements”子句中使用限定名称更为明显。我已相应地更新了我的答案。 - Sotirios Delimanolis
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接