2010-01-30 14 views
6

Sto provando a inviare oggetti per separare il metodo in base alla loro sottoclasse.Come richiamare un metodo java basato su un tipo di sottoclasse?

Ad esempio, consideriamo quei 2 oggetti

class A extends I {} 
class B extends I {} 

e il metodo

void dispatch(I i) {} 

in dispatch(), vorrei richiamare un metodo in base al tipo di i. Quindi se i è effettivamente di tipo A, verrà chiamato il metodo handlerA(A a). Se è di tipo B, verrà chiamato handlerB(B b) e così via ... Ho provato con l'overloading del metodo, ma suppongo che non funzioni in questo modo

qual è il modo migliore per raggiungere questo obiettivo? Vorrei evitare di usare if/else ...

Grazie in anticipo,

edit: non riesco a modificare alcuna di queste classi.

risposta

3

Così I si dichiara il metodo handler(), ed attuare in modo appropriato (cioè diverso) sia A e B.

Si tratta di polimorfismo :)

+0

Questo presuppone che 'handler()' senso avere su 'A' e' B'. Se questo è il caso, la tua risposta è corretta al 100%. –

+0

Kevin: hai ragione, lo fa. Ma solo tipo di. Continuo a pensare che all'OP manchi il concetto di polimorfismo sottostante, e anche se il mio suggerimento esatto non è adatto, penso che alcuni schemi di una funzione/proprietà in "I" siano la strada da seguire. –

+0

se handler() è in I, e sia A che B implementano I, ma non ha senso avere handler() su entrambi, penso che ci siano ** probabilmente ** altri problemi. – Carl

2

Utilizzare il Visitor Pattern.

In breve, hanno I dichiarare un metodo accept(Visitor<T> ...), e hanno Visitor esporre onA(A ...), onB(B ...), ecc metodi. Le implementazioni dell'interfaccia I chiameranno il metodo appropriato sul passato in Visitor<T>.

Probabilmente non ne vale la pena (a causa del boilerplate) se si hanno solo 2 classi concrete, ma da qualche parte attorno ai 3 o 4 inizia a valerne la pena - se non altro per evitare duplicati if-else.

1

Dal momento della modifica, presumo che non sia possibile modificare A, B e I; questo porta a una brutta notizia:

È possibile ereditare da A dicono C in questa classe (C) si può chiamare super.dispatch() modo da poter raggiungere la classe di base A.dispatch().

  • Ma grazie al design (eredità sconsiderata) non è possibile raggiungere I. Sarebbe come chiamare super.super che non è consentito

  • In Java, non è possibile chiamare super(). Super() .. I bambini hanno accesso ai loro genitori, ma non ai loro nonni.

Quindi sei vittima di un cattivo design. MODIFICA: risolto errore di battitura

0

Sembra che l'unico modo per farlo sia utilizzare il controllo del tipo. Capisco che questo non dovrebbe essere incoraggiato, ma ...

void dispatch(I i) 
{ 
    if(i instanceof A) 
    { 
     handlerA(); 
    } 
    else 
    { 
     handlerB(); 
    } 
} 

Ma seriamente, se puoi evitarlo del tutto, non scrivere codice come questo. Se non riesci a modificarli, potresti per caso estendere A e B, aggiungere un altro metodo handler() per entrambi e usare queste nuove sottoclassi invece di A e B?

0

Penso che in questo caso lo Adapter Pattern sia più applicabile del Pattern visitatore.

+0

come esattamente? (15) – Bozho

0

Se si potesse utilizzare Scala, è possibile scrivere

i match { 
    case a: A => handlerA(a) 
    case b: B => handlerB(b) 
    case _ => throw new Exception("Unknown i: " + i.toString) 
} 
Problemi correlati