我正在尝试根据子类将对象分派给单独的方法。
例如,考虑那两个对象
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语句......
提前致谢,
编辑:我无法修改任何这些类。
答案 0 :(得分:4)
简而言之,让I
声明accept(Visitor<T> ...)
方法,让Visitor
公开onA(A ...)
,onB(B ...)
等方法。您对I
接口的实现将在传递的Visitor<T>
。
它可能不值得(由于样板文件),如果你只有2个具体类,但在3或4左右它开始值得 - 如果只是为了避免重复的if-else结构。
答案 1 :(得分:3)
因此,在I
中,您声明了handler()
方法,并在A
和B
中适当地(即以不同方式)实施。
这是多态性:)
答案 2 :(得分:1)
自编辑以来,我认为你无法编辑A,B和I; 这导致了坏消息:
您可以在此类(C)中继承A
说C
,您可以致电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)
}