我在使用instanceof
运算符时遇到了麻烦。我正在努力避免这种情况。基本上,我具有以下结构:
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 }
我要指出的重点是:我想对该函数进行参数重载,但是它没有按我的预期工作(编译错误)。我在努力避免:
void parseShape(Shape s)
{
if (s instanceof Triangle) ...
}
更新:似乎共识是创建一个基类方法:parseShape()
起重。我想澄清一下我的问题:这个问题的动机与观察者模式有关。假设我有以下Observer对象有效负载方法:
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类中。或者,您可以使用“访客”模式。 this thread解决方案中显示了一个巧妙的反射技巧,可以避免Java中完整访问者模式的复杂性。
更新:
这是访客模式的秘诀:
公共(public)接口(interface)ShapeVisitor {
visit(三角形);
visit(Rectangle);
//...
}
Shape
中,声明一个抽象方法acceptVisitor
:类Shape {
公共(public)抽象无效acceptVisitor(ShapeVisitor visitor);
}
acceptVisitor
:类Triangle扩展Shape {
公共(public)无效acceptVisitor(ShapeVisitor访问者){
visitor.visit(this);
}
}
ParseVisitor
类以实现ShapeVisitor
并实现所有必需的方法(只需将每个parseShape
方法重命名为visit
)。 这样做的好处是,首先,它将解析代码保留在Shape层次结构之外,并将其集中在一个单独的解析类中;然后,将其集中在一个单独的解析类中。其次,如果您以后决定需要执行其他操作(例如渲染),则可以应用相同的图案,而无需更改任何Shape类。这种方法最大的缺点是,如果决定添加另一个
ShapeVisitor
子类,则必须更改所有实现Shape
的类。关于java - instanceof与多态,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6119087/