3

我对 Java 比较陌生。在阅读了一些有关寻路的信息后,我阅读了有关使用空类作为“ interface”的信息,用于未知对象类型。

我正在开发基于医院主题的 Java 游戏。到目前为止,用户可以建立一个接待处和一个全科医生的办公室。它们是两种不同类型的对象,一种是 a Building,一种是 a ReceptionDesk。(在我的班级结构中。)

我的班级结构是这样的:

GridObject-->Building
GridObject-->Item-->usableItem-->ReceptionDesk.

当可用物品可以旋转而建筑物不能旋转时,问题就出现了。鼠标单击事件在网格上,因此调用相同的方法。GP的办公室是a Building,接待处是a ReceptionDesk。唯有ReceptionDesk方法rotate。右键单击网格时,如果处于构建模式,我必须使用此“if”语句:

if (currentBuilding.getClass.equals(ReceptionDesk.getClass)

然后我必须创建一个新的ReceptionDesk,使用该rotate方法,并将那个接待台放回currentBuilding GridObject.

我不确定我是否用这个问题很好地解释了自己。对不起。我对 Java 还是很陌生。我将尝试回答任何问题,如果需要,我可以发布更多代码片段。我不知道可能有办法解决不知道对象类别的问题,但是我也可能以错误的方式解决它。

直到我看到这个网站上的回复如此快速和有帮助时,我才打算研究这个!:)

提前致谢。

相对

4

3 回答 3

7

您不想在对您的情况进行某些操作之前检查对象的类。你应该使用polymorphism。你想让接口定义一些方法。每个类都实现这些方法。通过接口引用对象,并让这些对象的各个实现将它们的值返回给调用者。

如果您再描述一些您认为需要的物品,这里的人们会对您应该如何布置它们有意见。但是根据您提供的内容,您可能需要一个定义一些通用方法的“Building”接口。您可能还想要一个“UsableItem”接口或更通用的东西。医院可以是一个实现构建的类。ReceptionDesk 可以实现 UsableItem。建筑内部可以有一个 UsableItem 网格。

如果 rotate() 是所有实际工作的家具的通用方法,您可以考虑创建一个 AbstractUsableItem 类,该类是实现 UsableItem 的抽象类并提供 rotate() 方法。如果每个实现类中的rotate 不同,那么接口中就会有该方法,但是每个类(如ReceptionDesk)都会使用rotate() 方法做自己的事情。您的代码将执行以下操作:

UsableItem desk = new ReceptionDesk();
desk.rotate()

在您的示例中,如果您在屏幕上单击鼠标旋转了它下面的对象,并且您确实需要在执行类似操作之前检查对象是否可以旋转,您会这样做

if (clickedObject instanceOf UsableItem) {
  ((UsableItem) clickedObject).rotate();
}

其中 UsableItem 是接口或抽象类。有些人觉得所有的设计都应该通过接口契约来完成,并为每种类型的类建议一个接口,但我不知道你是否必须走那么远。

于 2009-04-09T22:18:10.593 回答
3

您可能会考虑朝着完全不同的方向前进,让对象自己决定采取什么样的行动。例如,GridObject 接口可能会为 handleRightClick()、handleLeftClick() 等指定函数声明。在这种情况下,您要说的是“任何自称为 GridObject 的类都需要指定当它们被右键单击时会发生什么”。

因此,在 Building 类中,您可以实现 handleRightClick 以不执行任何操作(或返回错误)。在 ReceptionDesk 类中,您将实现 handleRightClick 来旋转桌子。

您的代码片段将变为:

currentBuilding.handleRightClick(... any necessary parameters ...);
于 2009-04-09T22:46:06.347 回答
1

你担心是对的。面向对象设计的一个好的经验法则是,每当您使用类似if(x instanceof Y)or的构造时if(x.getClass().equals(Y.class)),您应该开始考虑向上或向下移动方法,或提取新方法。

Elliot 和 John 都提出了关于你可以去的非常不同的方向的好主意,但他们都对,你肯定应该朝着某个方向前进。面向对象的设计通过使不同种类的行为的分支更加隐含来帮助您的代码变得更加清晰。检查您正在查看的对象类型并据此确定要执行的操作可能会破坏使用面向对象设计的目的。

我还应该警告您,接口并不完全是一个空类。具有抽象方法和接口的空抽象类之间存在一些显着差异。与其将接口视为空类,不如将接口视为契约。通过实现接口,您的类承诺提供接口中列出的每个方法。

于 2009-04-09T22:57:47.753 回答