多个操作取决于传递的对象的类型
Posted
技术标签:
【中文标题】多个操作取决于传递的对象的类型【英文标题】:Multiple operations depending on the type of the object passed 【发布时间】:2011-02-15 01:21:56 【问题描述】:假设我创建了一个传递对象的方法,并且该方法将根据传递的对象执行操作。我应该如何识别对象?
我曾想过使用类名来标识对象,但这可能不切实际,因为我很容易更改对象的类名,并且在以后的开发过程中会让人头疼。我说的对吗?
编辑:例如,我有物体球和炸弹。如果我有另一个名为墙的对象,并且墙具有解决与墙碰撞的方法(例如碰撞球和炸弹的坐标),但根据碰撞对象(即球和炸弹)有不同的逻辑
【问题讨论】:
更多上下文会很好。这对于一个有用的建议来说有点太笼统了。 您最好使用接口,这样您就可以为这些对象使用通用类型。 没错,因为我现在只能说,这种方法是错误的。应该在类的层次结构中(您期望作为参数获得),然后多态将是一个解决方案。 【参考方案1】:此代码将引导您使用switch
考虑使用多态性。这将自动取消命名问题。
【讨论】:
【参考方案2】:您要的是instanceof
运算符。
if (object instanceof SomeClass)
// do something
else if (object instanceof SomeOtherClass)
// do something else
但是,这不是一个好习惯。相反,您可以使用所谓的双重调度。使传递的对象符合根据其他类定义操作的接口。所以:
public interface ThrowableItem
void throwAt(Wall wall);
public class Wall
void accept(ThrowableItem item)
item.throwAt(this);
然后在Ball
和Bomb
中提供适当的实现(两者都实现ThrowableItem
)
查看Visitor pattern - 您可以将操作移至知道如何处理每个对象的碰撞的WallVisitor
。
【讨论】:
这就是我在回答中所说的。您加倍努力并编写了一些代码。如果您提到抽象类以及哪个是更好的选择,我将删除我的答案! 用一个例子编辑了我的问题,以稍微形象化这个问题。根据我对您的代码 sn-p 的理解,我应该从碰撞对象类中的方法解析碰撞对象的坐标。这是正确的吗? @mixim - 我更新了示例中的类/接口的名称以遵循您的名称 @mixm 在这种情况下,逻辑应该在球类和炸弹类中处理。由于它是完全相同的用例,只是每种类的行为不同,因此您需要使用抽象类(或实现接口)作为基础,并且球和炸弹将从它继承。抽象方法可以称为碰撞()之类的东西。然后墙会调用碰撞对象的碰撞()方法,对象应该确定发生了什么。 鉴于您更新的描述,我建议您查看red3d.com/cwr/steer/Containment.html,特别是因为“车辆和障碍物之间的通信由通用表面协议处理:车辆询问障碍物是否有给定的探测点位于曲面内部,如果是,则要求曲面上最近的点和该点的法线。因此,转向行为不需要了解曲面的形状。"【参考方案3】:这取决于操作是什么。它们有什么关系?是不是你有很多对象做同样的事情,但方式略有不同?例如,假设我有一个应该打印文档的方法,但我希望使用相同的方法来打印 pdf 和 doc 文件。
如果您的情况与此类似,那么您可能需要考虑使用继承,如下所示:创建一个超类,在我的示例中,我们使用 print() 方法将其称为 Document。 print 方法不需要做任何事情。然后为每种类型的文档创建一个子类,所以我最终会得到一个 PdfDocument 和一个 DocDocument 子类。它们中的每一个都将为 print() 提供一个实现,可以打印与其相关的文档类型。
那我写的方法是:
public void printDocument(Document d)
d.print();
也就是说,通过定位超类类型,我不必担心每种类型的文档执行的具体操作。这样我就避免了检查传递给我的方法的对象类型的代码。它使代码对未来的扩展更加健壮。
【讨论】:
【参考方案4】:根据上下文,您可能还想为可能传入的不同类型提供不同的方法(重载)。
public void doSomething(TypeA object)
// TypeA specific stuff
public void doSomething(TypeB object)
// TypeB specific stuff
【讨论】:
【参考方案5】:您可以使用instanceof
,但请注意其中的陷阱。对于以下子类,这将是“真”:
if (subclass instanceof superclss) // returns true
【讨论】:
以上是关于多个操作取决于传递的对象的类型的主要内容,如果未能解决你的问题,请参考以下文章