2013-12-14 12 views
5

Ho bisogno di avere una variabile in una classe che è un'istanza di classe "ClasseA" ma che implementa anche l'interfaccia "InterfaceI".Variabile membro che deve estendere la classe A e implementare alcune interfacce

Ovviamente questo può essere fatto per l'uno o l'altro facilmente:

private ClassA mVariable; 
private InterfaceI mVaraible; 

ma come faccio a far rispettare l'oggetto sia estende ClassA e implementa InterfaceB? Qualcosa di simile:

private <? extends ClassA & InterfaceI> mVaraible; 

è ciò di cui ho bisogno ma non ho idea della sintassi o se è addirittura possibile. Ho anche bisogno di un get e il metodo set, ma che può essere fatto con i generici (credo?)

La soluzione più ovvia è

public class ClassB extends ClassA implements InterfaceI{ 
    //whatever here 
} 

Comunque sia InterfaceI e ClasseA fanno parte di un libary esterna, questo libary ha classi che estendono ClassA e InterfaceI e non posso modificarle per farle estendere ClassB, quindi questa soluzione non funzionerà.

+1

Non è possibile, in fondo. È possibile controllarlo quando si imposta la variabile, quindi eseguire il cast quando è necessario ... ma non è possibile esprimere tale vincolo sulla variabile stessa, senza rendere generica la classe. –

+0

c'è un po 'di magia in Java8 per consentire l'ereditarietà multipla, o una sorta di mix-in ... – Thufir

+0

@Jon Skeet Come verificherai quando imposti la variabile? – jtedit

risposta

1

Ho trovato una soluzione alquanto problematica.

La classe contiene sia un riferimento ClassA e InterfaceI come segue:

private ClassA mItemClassA; 
private InterfaceI mItemInterfaceI; 

Il metodo set sembra quindi simili:

public void setVaraible(ClassA item){ 
    assert (item instanceof InterfaceI); 
    mItemClassA = item; 
    mItemInterfaceI = (InterfaceI) item; 
} 

Altri tipi di questo potrebbe essere un'eccezione, tornando falso , ecc. se l'elemento non è un'istanza di InterfaceI

Altri metodi nella classe possono quindi chiamare funzioni da InterfaceI e ClassA utilizzando mItemClassA a nd mItemInterfaceI.

Non ho intenzione di implementare un metodo get per ora, ma se lo facessi ci sarebbe probabilmente una versione per ottenere l'interfaccia e una versione per ottenere la classe.

+0

preferisco usare le eccezioni. Le asserzioni non sono selezionate, per impostazione predefinita. È una bandiera in più che devi accendere. +1 btw. –

0

Si può fare questo con i tipi generici di classe come questo:

private class ClassB <R extends ClassA & InterfaceI> { 
    R mVaraible; 
} 
Problemi correlati