如何根据子类类型调用java方法?

时间:2010-01-30 22:42:59

标签: java oop polymorphism

我正在尝试根据子类将对象分派给单独的方法。

例如,考虑那两个对象

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

和方法

void dispatch(I i) {}

dispatch()中,我想根据i的类型调用方法。因此,如果i实际上是A类型,则将调用handlerA(A a)方法。如果它是B类型,则会调用handlerB(B b),依此类推......我尝试使用方法重载,但我猜它不会这样工作

实现这一目标的最佳方法是什么?我想避免使用if / else语句......

提前致谢,

编辑:我无法修改任何这些类。

6 个答案:

答案 0 :(得分:4)

使用Visitor Pattern

简而言之,让I声明accept(Visitor<T> ...)方法,让Visitor公开onA(A ...)onB(B ...)等方法。您对I接口的实现将在传递的Visitor<T>

中调用适当的方法

它可能不值得(由于样板文件),如果你只有2个具体类,但在3或4左右它开始值得 - 如果只是为了避免重复的if-else结构。

答案 1 :(得分:3)

因此,在I中,您声明了handler()方法,并在AB中适当地(即以不同方式)实施。

这是多态性:)

答案 2 :(得分:1)

自编辑以来,我认为你无法编辑A,B和I; 这导致了坏消息:

您可以在此类(C)中继承AC,您可以致电super.dispatch(),以便您可以访问基类A.dispatch()

  • 但由于设计(未经考虑的继承),您无法到达I。这就像调用不允许的super.super一样

  • 在Java中,你不能调用super()。super()..孩子可以访问他们的父母,但不能访问他们的祖父母。

所以你是糟糕设计的受害者。 编辑:修复错误

答案 3 :(得分:0)

看起来你能做到这一点的唯一方法是使用类型检查。我知道这不应该被鼓励,但是......

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

但严重的是,如果你可以完全避免它,不要写这样的代码。如果你不能修改它们,你是否可以扩展A和B,为两者添加一个不同的handler()方法并使用这些新的子类而不是A和B?

答案 4 :(得分:0)

我认为在这种情况下Adapter Pattern比访客模式更适用。

答案 5 :(得分:0)

如果你可以使用Scala,你可以写

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