Cyclical inheritance and interfaces - class A cannot implement the interface of class B, while class B implements the interface

I have:

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

So, if I understand correctly, circular inheritance occurs because:

The compiler goes into A and says: "Hey, A implements BListener, let go of our BListener!"

Then, when he tries to find the BListener, he eventually gets B , which says:

"Hey, BListener, you need A inside B! BUT WAIT! B needs AListener! Let go find AListener!"

And then he gets to A, repeat. Did I get it right?

By the way, this compilation error occurred to me when developing Android.

+5
source share
2 answers

This can help bring it out.

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

A wonderful circle. You cannot create one of them without the other existing ones.

Is the compiler a squirrel with ADHD high on coffee chasing its own tail?

No, because the protein didn't stop (until the caffeine ran out). The compiler searches for this and then refuses.

Note. Eclipse has a bug that allows this setting.

+6
source

After further investigation, I was initially mistaken.

The technical explanation for the behavior you noticed is as follows

In the chapter "Java Language Specification" on Superclasses and Subclasses

The class C directly depends on the type of T if T is referred to in extends or implements in C either as a superclass, or as a superinterface, or as a qualifier in the full form of a superclass or superinterface.

Class C depends on the reference type T if any of the following is true:

  • C directly depends on T
  • C directly depends on interface I , which depends (ยง9.1.3) on T
  • C directly depends on the class D , which depends on T (using this definition recursively).

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

Take your full-name code for using types, assuming the classes were declared in the com.example package:

 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 JLS above

  • A directly dependent on BListener , as it is mentioned in its implements clause.
  • A directly depends on B , as it is referred to as a qualifier in the fully qualified name of the superinterface ( BListener is com.example.B.BListener )
  • B directly dependent on AListener , as it is mentioned in its implements clause.
  • B directly depends on A , since it is referred to as a qualifier in the fully qualified name of the superinterface ( AListener is com.example.A.AListener )
  • A directly depends on B , which depends on A

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


In Eclipse, an error occurs if you qualify 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, this is not the case. I will open a mistake with them.

+2
source

Source: https://habr.com/ru/post/1236809/


All Articles