2015-11-25 25 views
5

ho:eredità ciclico e le interfacce - classe A non può implementare l'interfaccia di classe B, mentre la classe B implementa un'interfaccia

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

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

Quindi, se ho capito bene l'eredità ciclico accade perché:

Il il compilatore va a A e dice "hey, A implementa BListener, andiamo a trovare BListener!"

Poi, quando si cerca di trovare BListener, si arriva alla fine a B, che si dice:!!!

"Ehi, BListener, necessario per la A è all'interno B MA ATTENDERE B ha bisogno di AListener Diamo vai a trovare AListener! "

E quindi arriva ad A, ripetere. Ho capito bene?

A proposito, questo errore di compilazione mi è successo sullo sviluppo Android.

+0

Perché questa domanda ha avuto esito negativo? –

+0

_questo è successo_ Che cos'è _questo? Hai ricevuto un errore di compilazione? Quale errore di compilazione? –

risposta

6

Può essere utile estrarlo.

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

Un bel cerchio. Non puoi crearne uno senza che gli altri esistano già.

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

No perché uno scoiattolo non si ferma (fino a quando la caffeina si esaurisce). Il compilatore cerca questo e poi si arrende.

Nota: Eclipse presenta un bug che consente questa configurazione.

+0

È uno scoiattolo molto determinato! Grazie, quindi ho capito bene. Accettare tra 7 minuti. –

2

Dopo ulteriori indagini, inizialmente mi sbagliavo.

La spiegazione tecnica per il comportamento si stanno notando è il seguente

Dal capitolo linguaggio Java Specification su 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.

Prendiamo il codice, con nomi completi per tipo utilizza, assumendo il le classi sono stati dichiarati in confezione com.example:

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

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

Seguendo le regole della JLS sopra

  • A dipende direttamente BListener, perché è menzionato nella sua implements clausola.
  • A dipende direttamente B, perché è menzionato come qualificazione nel nome completo di un superinterfaccia (BListener è com.example.B.BListener)
  • B dipende direttamente AListener, perché è menzionato nella sua implements clausola.
  • B dipende direttamente A, perché è menzionato come qualificazione nel nome completo di un superinterfaccia (AListener è com.example.A.AListener)
  • A dipende direttamente B che dipende A.

Pertanto A dipende da A e si dovrebbe verificare un errore di compilazione.


In Eclipse, l'errore si verifica se si qualificano i nomi

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

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

Se si utilizza import dichiarazioni, tuttavia, non è così. Aprirò un bug con loro.

+0

Sto ancora ricevendo "ereditarietà ciclica che coinvolge com.example.B" in intelliJ. –

+0

E a Maven. Errore [ERRORE] /home/mlk/code/test_project/src/test/java/com/example/A.java:[4,7]: eredità ciclica che coinvolge A' –

+0

@mlk Potrei sbagliarmi, qui. Eclipse compila questo senza problemi. Ho intenzione di indagare ulteriormente. –