开发者

How to invoke a java method based on a subclass type?

I'm trying to dispatch objects to separate method according to their subclass.

For instance, consider those 2 objects

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

and the method

void dispatch(I i) {}

in dispatch(), I'd like to invoke a method according to the type of i. Hence if i is actually of type A, the handlerA(A a) method will be called. If it's of type B, handlerB(B b) will be called, and so on ... I tried with method ov开发者_StackOverflow中文版erloading but I guess it doesn't work this way

what is the best way to achieve this ? I'd like to avoid using if/else statement ...

Thanks in advance,

edit: I can't modify any of those classes.


Use the Visitor Pattern.

In short, have I declare an accept(Visitor<T> ...) method, and have Visitor expose onA(A ...), onB(B ...), etc. methods. Your implementations of the I interface will call the appropriate method on the passed in Visitor<T>.

Its probably not worth it (due to boilerplate) if you only have 2 concrete classes, but somewhere around 3 or 4 it starts being worth it - if just to avoid duplicated if-else constructs.


So in I you declare the handler() method, and implement it appropriately (i.e. differently) in both A and B.

This is Polymorphism :)


Since your edit, I assume you cannot edit A,B and I; this leads to bad news:

You can inherit from A say C in this class (C) you may call super.dispatch() so you can reach the base class A.dispatch().

  • But due to design (unconsidered inheritance) you cannot reach I. This would be like calling super.super which is not allowed

  • In Java, you can't call super().super().. Childs have acces to their parents, but not to their grandparents.

So you're a victim of bad design. EDIT: fixed typo


Looks like the only way you can do this is to use type checking. I understand that this is not supposed to be encouraged, but...

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

But seriously, if you can avoid it at all, do not write code like this. If you can't modify them, could you by any chance extend A and B, add in a different handler() method for both and and use these new subclasses instead of A and B?


I think that the Adapter Pattern is more applicable than the Visitor Pattern in this case.


If you could use Scala, you can write

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜