2010-01-30 14 views
6

Estoy tratando de enviar objetos para separar el método de acuerdo con su subclase.¿Cómo invocar un método java basado en un tipo de subclase?

Por ejemplo, considere los 2 objetos

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

y el método

void dispatch(I i) {} 

en dispatch(), me gustaría para invocar un método de acuerdo con el tipo de i. Por lo tanto, si i es realmente de tipo A, se llamará al método handlerA(A a). Si es de tipo B, se llamará a handlerB(B b), y así sucesivamente ... Intenté con la sobrecarga de métodos, pero supongo que no funciona de esta manera

¿cuál es la mejor manera de lograr esto? Me gustaría evitar el uso de if/else ...

Gracias de antemano,

editar: No puedo modificar cualquiera de esas clases.

Respuesta

3

Así que en I que declarar el método handler(), y poner en práctica de manera apropiada (es decir de manera diferente), tanto en A y B.

Este es el polimorfismo :)

+0

Esto supone que 'manejador()' tiene sentido tener en 'A' y 'B'. Si ese es el caso, tu respuesta es 100% correcta. –

+0

Kevin: Tienes razón, lo hace. Pero solo un poco. Sigo pensando que al OP le falta el concepto subyacente de polimorfismo, y aunque mi sugerencia exacta no sea adecuada, creo que algún esquema de una función/propiedad en 'I' es el camino a seguir. –

+0

si el controlador() está en I, y tanto A como B implementan I, pero no tiene sentido tener handler() en ambos, creo que hay ** probablemente ** otros problemas. – Carl

2

Uso del Visitor Pattern.

En resumen, han I declarar un método accept(Visitor<T> ...), y tienen Visitor exponga onA(A ...), onB(B ...), etc. métodos. Sus implementaciones de la interfaz I llamarán al método apropiado en el aprobado en Visitor<T>.

Probablemente no valga la pena (debido a la repetición estándar) si solo tiene 2 clases concretas, pero en algún lugar alrededor de 3 o 4 comienza a valer la pena, solo para evitar construcciones if-else duplicadas.

1

Desde su edición, asumo que no puede editar A, B e I; esto conduce a malas noticias:

Puede heredar de A dicen C en esta clase (C) puede llamar super.dispatch() para que pueda llegar a la clase base A.dispatch().

  • embargo, debido al diseño (herencia unconsidered) no puede comunicarse con I. Esto sería como llamar a super.super que no está permitido

  • En Java, no puedes llamar a super(). Super() .. Los niños tienen acceso a sus padres, pero no a sus abuelos.

Eres una víctima del mal diseño. EDITAR: error tipográfico fijo

0

Parece que la única manera de hacerlo es utilizar la verificación de tipo. Entiendo que esto no se debe alentar, pero ...

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

Pero en serio, si puede evitarlo en absoluto, no escriba código como este. Si no puede modificarlos, ¿podría, por casualidad, extender A y B, agregar un método controlador diferente() para ambas y usar estas nuevas subclases en lugar de A y B?

0

Creo que el Adapter Pattern es más aplicable que el Patrón de visitante en este caso.

+0

¿cómo exactamente? (15) – Bozho

0

Si usted podría utilizar Scala, puede escribir

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