instanceof与多态 [英] instanceof versus polymorphism

查看:132
本文介绍了instanceof与多态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在instanceof运算符上遇到麻烦.我正在努力避免这种情况.基本上,我具有以下结构:

I am having troubles with the instanceof operator. I'm trying to avoid it. Basically, I have the following structure:

class Shape {}
class Triangle extends Shape {}
class Rectangle extends Shape {}

ShapeParser s;
while (s.hasNext())
     parseShape(s.next()); // returns a Shape object

void parseShape(Triangle t) { // do stuff } // KEY POINT HERE
void parseShape(Rectangle t) { // etc }

我要指出的重点是:我想对该函数进行参数重载,但是它无法按我的预期工作(编译错误).我正在努力避免:

The key point I'm making is: I want to do a parameter overload of the function, but it's not working as I intend it to (compile-error). I am trying to avoid:

void parseShape(Shape s)
{
     if (s instanceof Triangle) ...
}

更新:似乎共识是创建一个基类方法:parseShape()做 起重.我想澄清一下我的问题:这个问题的动机与观察者模式有关.假设我有以下Observer对象有效负载方法:

UPDATE: it seems that the consensus is to create a base class method: parseShape() to do the lifting. I wanted to clarify my question: the motivation of this question is relative to the observer pattern. Suppose I have the following Observer object payload method:

    public void update(Observable obj, Shape objectPayload){} 
// note: the objectPayload is usually of type Object

代替执行:

public void update(Observable obj, Shape objectPayload)
{
       if (objectPayload instanceof Triangle)
          // do stuff
       else if (objectPayload instanceof Rectangle)
          // etc
}

我想做:

public void update(Observable obj, Shape objectPayload)
{
       parseShape(objectPayload);
}

    void parseShape(Triangle t) {  } // do stuff
    void parseShape(Rectangle t) { }

推荐答案

您可以将parseShape移到每个Shape类中.或者,您可以使用访客"模式.在此线程的解决方案中,有一个巧妙的思考技巧可以避免复杂性. Java中的完整访问者模式.

You can move the parseShape into each Shape class. Alternatively, you can use the Visitor pattern. There's a neat trick with reflection shown in the solution to this thread that avoids the complexity of a full visitor pattern in Java.

更新:

以下是访问者模式的秘诀:

Here's a recipe for the visitor pattern:

  1. 声明一个接口:

  1. Declare an interface:


public interface ShapeVisitor {  
    visit(Triangle);  
    visit(Rectangle);  
    // ...  
}

  • Shape中,声明一个抽象方法acceptVisitor:

  • In Shape, declare an abstract method acceptVisitor:

    
    class Shape {
        public abstract void acceptVisitor(ShapeVisitor visitor);
    }
    

  • 在每个具体的类中,实现acceptVisitor:

    
    class Triangle extends Shape {
        public void acceptVisitor(ShapeVisitor visitor) {
            visitor.visit(this);
        }
    }
    

  • 声明您的ParseVisitor类以实现ShapeVisitor并实现所有必需的方法(只需将每个parseShape方法重命名为visit).

  • Declare your ParseVisitor class to implement ShapeVisitor and implement all the required methods (simply rename each of the parseShape methods to visit).

    首先,它可以将解析代码保留在Shape层次结构之外,并将其集中在一个单独的解析类中;第二,如果您以后决定需要执行其他操作(例如渲染),则可以应用相同的图案,而无需更改任何Shape类.这种方法最大的缺点是,如果决定添加另一个Shape子类,则必须更改所有实现ShapeVisitor的类.

    The nice things about this are, first, it keeps the parsing code out of your Shape hierarchy and centralizes it in a separate parsing class; second, if you later decide that you need to do some other operation (like, say, render), you can apply the same pattern without ever changing any Shape class. The big down side of this approach is that you will have to change all classes that implement ShapeVisitor if you decide to add another Shape subclass.

    这篇关于instanceof与多态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆