以下是我要做的事情:
class Foo {
private ArrayList<Widget> things; //Contains WidgetA, WidgetB and WidgetAB objects
//...
void process(int wIndex) {
process(things.get(wIndex);
}
private void process(WidgetA w) {
//Do things
}
private void process(WidgetB w) {
//Do other things
}
private void process(WidgetAB w) {
//Do completely different things
}
}
abstract class Widget {
//...
}
class WidgetA extends Widget {
//...
}
class WidgetB extends Widget {
}
class WidgetAB extends WidgetA {
}
基本上,一个单独的类从用户输入获取一个数组索引,并将其传递给process(int)方法,该方法应该启动一个特定于类型的process()方法来处理传递索引处的对象。问题是对象被视为Widget对象,而不是WidgetA等。我猜,我可以使用instanceof循环遍历类型,但我试图避免使用它。 process()方法中的逻辑需要访问Foo类中的私有字段,因此将它们移动到Widget子类可能不是最好的主意。
所以问题是,有没有办法为给定的Widget子类型调用正确的process()方法,而不使用instanceof?
答案 0 :(得分:3)
是的,请查看访客模式 - 也称为双重调度。
答案 1 :(得分:0)
另一个可能的解决方案是使用Java的反射API。例如:
class Foo {
private ArrayList<Widget> things; //Contains WidgetA, WidgetB and WidgetAB objects
//...
void process(int wIndex) {
Widget theWidget = things.get(wIndex);
try {
Class type = theWidget.getClass();
Class[] arg_types = new Class[]{type};
this.getMethod("process", arg_types).invoke(this, theWidget);
} catch (Exception e) {
//Could be SecurityException or NoSuchMethodException
}
}
private void process(WidgetA w) {
//Do things
}
private void process(WidgetB w) {
//Do other things
}
private void process(WidgetAB w) {
//Do completely different things
}
}
abstract class Widget {
//...
}
class WidgetA extends Widget {
//...
}
class WidgetB extends Widget {
}
class WidgetAB extends WidgetA {
}
这里的问题是您必须为process()
列表中的每种类型的对象定义things
方法,否则将在运行时抛出异常。如果您缺少实现,编译器将不会警告您。