不使用instanceof的向下转换和多态? (爪哇)

Posted

技术标签:

【中文标题】不使用instanceof的向下转换和多态? (爪哇)【英文标题】:Downcasting and polymorphism without using instanceof? (Java) 【发布时间】:2012-04-11 19:04:23 【问题描述】:

这是我正在尝试做的事情:

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?

【问题讨论】:

Is This Use of the "instanceof" Operator Considered Bad Design?的可能重复 【参考方案1】:

是的,看看访问者模式 - 也称为双重调度。

【讨论】:

【参考方案2】:

另一个可能的解决方案是使用 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 

这里的问题是您必须为things 列表中的每种类型的对象定义一个process() 方法,否则将在运行时引发异常。如果您缺少实现,编译器不会警告您。

【讨论】:

以上是关于不使用instanceof的向下转换和多态? (爪哇)的主要内容,如果未能解决你的问题,请参考以下文章

从零开始的Java开发1-4-3 多态:概念实现向上转型向下转型instanceof类型转换抽象类抽象方法

C++中的虚函数(类的向上转换,和向下转换)

多态的理解

继承--方法覆盖--多态

Java面向对象多态和接口

Java多态对象的类型转换和动态绑定