2010-01-30 6 views
6

J'essaye d'expédier des objets pour séparer la méthode selon leur sous-classe.Comment invoquer une méthode java basée sur un type de sous-classe?

Par exemple, considérons ces 2 objets

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

et la méthode

void dispatch(I i) {} 

à dispatch(), je voudrais invoquer une méthode selon le type de i. Par conséquent, si i est réellement de type A, la méthode handlerA(A a) sera appelée. Si c'est du type B, handlerB(B b) sera appelé, et ainsi de suite ... J'ai essayé avec la méthode de surcharge mais je suppose que cela ne fonctionne pas de cette façon

quelle est la meilleure façon d'y parvenir? Je voudrais éviter d'utiliser l'instruction if/else ...

Merci à l'avance,

modifier: Je ne peux pas modifier l'une de ces classes.

Répondre

3

Ainsi, dans I vous déclarez la méthode handler(), et mettre en œuvre de manière appropriée (à savoir différemment) dans les deux A et B.

C'est Polymorphisme :)

+0

Cela suppose que 'gestionnaire()' est logique d'avoir sur 'A' et' B'. Si c'est le cas, votre réponse est 100% correcte. –

+0

Kevin: Vous avez raison, c'est le cas. Mais seulement genre de. Je pense toujours que l'OP manque le concept sous-jacent du polymorphisme, et même si ma suggestion exacte ne convient pas, je pense qu'un schéma d'une fonction/propriété dans 'I' est la voie à suivre. –

+0

si handler() est dans I, et que A et B implémentent I, mais cela n'a pas de sens d'avoir handler() sur les deux, je pense qu'il y a ** probablement ** d'autres problèmes. – Carl

2

Utilisez le Visitor Pattern.

En bref, ont I déclarer une méthode accept(Visitor<T> ...), et ont Visitor exposer onA(A ...), onB(B ...), méthodes, etc.. Vos implémentations de l'interface I appellera la méthode appropriée sur le passé dans Visitor<T>. Cela ne vaut probablement pas le coup (en raison de la règle) si vous n'avez que 2 classes concrètes, mais quelque part autour de 3 ou 4 cela commence à en valoir la peine - si seulement pour éviter la duplication des constructions if-else.

1

Depuis votre modification, je suppose que vous ne pouvez pas modifier A, B et I; cela conduit à de mauvaises nouvelles:

Vous pouvez hériter de A dire C dans cette classe (C), vous pouvez appeler super.dispatch() afin que vous puissiez atteindre la classe de base A.dispatch().

  • Mais en raison de la conception (héritage inconsidéré) vous ne pouvez pas atteindre I. Ce serait comme appeler super.super qui n'est pas autorisé

  • En Java, vous ne pouvez pas appeler super(). Super() .. Les enfants ont accès à leurs parents, mais pas à leurs grands-parents.

Vous êtes donc victime d'un mauvais design. EDIT: typo fixe

0

Il semble que la seule façon d'y parvenir est d'utiliser la vérification de type. Je comprends que ce n'est pas censé être encouragé, mais ...Mais sérieusement, si vous pouvez l'éviter, n'écrivez pas du code comme ceci. Si vous ne pouvez pas les modifier, pourriez-vous par hasard étendre A et B, ajouter une méthode handler() différente pour les deux et utiliser ces nouvelles sous-classes au lieu de A et B?

0

Je pense que le Adapter Pattern est plus applicable que le modèle de visiteur dans ce cas.

+0

comment exactement? (15) – Bozho

0

Si vous pouvez utiliser Scala, vous pouvez écrire

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