Java 不使用instanceof的向下投射和多态性?(爪哇)

Java 不使用instanceof的向下投射和多态性?(爪哇),java,polymorphism,Java,Polymorphism,以下是我想做的事情: 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 t

以下是我想做的事情:

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 {
}
class-Foo{
私有ArrayList things;//包含WidgetA、WidgetB和WidgetAB对象
//...
无效过程(int wIndex){
进程(things.get)(wIndex);
}
私有作废流程(WidgetA w){
//做事
}
私有作废流程(WidgetB w){
//做其他事情
}
私有作废流程(WidgetAB w){
//做完全不同的事情
}
}
抽象类小部件{
//...
}
类WidgetA扩展小部件{
//...
}
类WidgetB扩展小部件{
}
类WidgetAB扩展了WidgetA{
}
基本上,一个单独的类从用户输入中获取一个数组索引,并将其传递给process(int)方法,该方法应该启动一个特定于类型的进程()方法在传递的索引处处理对象。问题是对象被视为小部件对象,而不是WidgetA等。我想我可以使用instanceof遍历类型,但我试图避免使用instanceof。 process()方法中的逻辑需要访问Foo类中的私有字段,因此将它们移动到Widget子类可能不是最好的主意


所以问题是,有没有一种方法可以在不使用instanceof的情况下为给定的小部件子类型调用正确的process()方法?

是的,请查看访问者模式-也称为双重分派。

另一种可能的解决方案是使用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 {
}
class-Foo{
私有ArrayList things;//包含WidgetA、WidgetB和WidgetAB对象
//...
无效过程(int wIndex){
Widget theWidget=things.get(wIndex);
试一试{
Class type=theWidget.getClass();
类[]arg_types=新类[]{type};
getMethod(“process”,arg_类型).invoke(this,theWidget);
}捕获(例外e){
//可以是SecurityException或NoSuchMethodException
}
}
私有作废流程(WidgetA w){
//做事
}
私有作废流程(WidgetB w){
//做其他事情
}
私有作废流程(WidgetAB w){
//做完全不同的事情
}
}
抽象类小部件{
//...
}
类WidgetA扩展小部件{
//...
}
类WidgetB扩展小部件{
}
类WidgetAB扩展了WidgetA{
}
这里的问题是,您必须为
事物
列表中的每种类型的对象定义
process()
方法,否则在运行时将引发异常。如果缺少实现,编译器将不会警告您。

可能重复的