2013-03-29 7 views
5

ho la seguente gerarchia in java:Override interfaccia ereditata con sottotipo con i generici

interface ObserverA {} 

interface A { 
    void method1(); 
    addObserver(Observer o); 
} 

E voglio estenderlo in questo modo:

interface ObserverB extends ObserverA{} 

interface B extends A { 
    void method2(); 
    addObserver(ObserverB o); 
} 

in modo tale che il addObserver() il metodo di B sostituisce lo stesso metodo in A. Poiché non funziona, le implementazioni di B dovrebbero implementare entrambe le versioni di addObserver(), non ne avrei avuto uno solo.

si può fare in un modo intelligente che non comporta dover parametrizzare A come:

interface A<O extends Observer> { 
    addObserver(O o); 
} 

soluzioni hacker sono i benvenuti!

+0

Il tipo generico è sempre un modo migliore per fare ciò in cui non si conosce il tipo – Biswajit

risposta

1

ne dite -

interface ObserverA {} 

interface A { 

    <T extends ObserverA> void addObserver(T o); 
} 

e -

interface ObserverB extends ObserverA{} 

interface B extends A{ 

    // do nothing, or omit this interface entirely. 

} 

in modo che sarete in grado di passare qualsiasi tipo che eredita ObserverA come argomento al metodo addObserver.

Se stai cercando una piccola spiegazione, allora continua a leggere.

Ho modificato il metodo nella prima interfaccia per utilizzare Bounded Type Parameter. Il modo in cui è dichiarato, consentirà a tutti gli oggetti di essere passati come argomento al metodo addObserver a condizione che il tipo sia ObserverA o che erediti da ObserverA. Poiché il tuo ObserverB eredita da ObserverA, puoi passare in sicurezza oggetti di entrambi i tipi ObserverA e ObserverB a questo metodo come argomento.

EDIT

Dal vostro chiarimento, sembra che si dovrebbe creare due diverse interfacce senza alcun rapporto gerarchico tra loro. Sembrano non correlati perché si desidera fornire implementazioni solo per il secondo metodo, evitando il primo. Quindi, piuttosto che forzarti a fornire l'implementazione del metodo dalla prima interfaccia, dovresti separarli. C'è anche un principio OOP per questo - Interface Segregation Principle.

+0

Ho già provato questo, il problema è che 'B' accetterebbe qualsiasi' 'e voglio che accetti solo 'ObserverB' (o' 'per quella materia) – Chirlo

+0

@Chirlo: Vedi la mia modifica. –

+0

L'esempio che ho dato è una versione semplificata di ciò che voglio fare. 'A' sarebbe un'interfaccia più complessa che' B' ha bisogno di estendere, ma i suoi osservatori sono anche più complessi di quelli di 'A'. Ho curato la questione in modo da riflettere il fatto che la 'B' estende la funzionalità da 'A' – Chirlo

2

Anche se il tuo esempio mostra qualcosa di diverso, suppongo che ti piacerebbe avere una interfaccia generica implementata da classi diverse. Date un'occhiata a questo:

public interface Observer<T> { 
    void addObserver(T t); 
} 

public class First implements Observer<First> { 
    @Override 
    public void addObserver(First t) { 
    } 
} 

public class Second implements Observer<Second> { 
    @Override 
    public void addObserver(Second t) { 
    } 
} 

Come si può vedere sia prima e la seconda classi implementano la stessa interfaccia, ma con diversi tipi di parametri. Essi parametrizzano l'interfaccia implementata con themselved, ma invece di scrivere Observer<Frist> puoi scrivere Observer<Integer> o qualsiasi altra cosa desideri.

EDIT

tenendo conto delle vostre chiarimenti questa sarebbe un'implementazione generica del codice all'interno della gerarchia dell'interfaccia hai presentato.

interface ObserverA {} 

interface A<T> { 
    void method1(); 
    void addObserver(T o); 
} 

interface ObserverB extends ObserverA {} 

interface B extends A<ObserverB> { 
    void method2(); 
} 
4

Non è possibile limitare i tipi di parametri del metodo in sottointerfacce o sottoclassi. È possibile solo ampliarli, poiché le implementazioni del sottotipo devono essere in grado di soddisfare il contratto del supertipo.

Analogamente, è possibile restringere tipi di ritorno ed eccezioni, ma non ampliarli, per lo stesso motivo.