问题
I'm rather new to Java. After just reading some info on path finding, I read about using an empty class as an "interface
", for an unknown object type.
I'm developing a game in Java based on hospital theme. So far, the user can build a reception desk and a GP's office. They are two different types of object, one is a Building
and one is a ReceptionDesk
. (In my class structure.)
My class structure is this:
GridObject-->Building
GridObject-->Item-->usableItem-->ReceptionDesk.
The problem comes when the usable item can be rotated and the building cannot. The mouse click event is on the grid, so calls the same method. The GP's office is a Building
and the reception desk is a ReceptionDesk
. Only the ReceptionDesk
has the method rotate
. When right clicking on the grid, if in building mode, I have to use this "if" statement:
if (currentBuilding.getClass.equals(ReceptionDesk.getClass)
I then have to create a new ReceptionDesk
, use the rotate
method, and the put that
reception desk back into the currentBuilding GridObject
.
I'm not sure if I'm explaining myself very well with this question. Sorry. I am still quite new to Java. I will try to answer any questions and I can post more code snippits if need be. I didn't know that there might be a way around the issue of not knowing the class of the object, however I may also be going about it the wrong way.
I hadn't planned on looking into this until I saw how fast and helpful the replies on this site were! :)
Thanks in advance.
Rel
回答1:
You don't want to check the class of an object before doing something with it in your case. You should be using polymorphism. You want to have the Interface define some methods. Each class implement those methods. Refer to the object by its interface, and have the individual implementations of those objects return their values to the caller.
If you describe a few more of the objects you think you need, people here will have opinions on how you should lay them out. But from what you've provided, you may want a "Building" interface that defines some general methods. You may also want a "UsableItem" interface or something more generic. Hospital could be a class that implements building. ReceptionDesk could implement UsableItem. Building could have a grid of UsableItem inside it.
If rotate() was a common method to all furniture that actually did some work, you may consider making an AbstractUsableItem class that was an abstract class implementing UsableItemand providing the rotate() method. If rotate was different in each implementing class, you would have that method in the interface, but each class, like ReceptionDesk would do its own thing with the rotate() method. Your code would do something like:
UsableItem desk = new ReceptionDesk();
desk.rotate()
In your example, if your mouse click on a screen rotated the object under it, and you really did need to check to see if the object could be rotated before doing something like that, you'd do
if (clickedObject instanceOf UsableItem) {
((UsableItem) clickedObject).rotate();
}
where UsableItem was the interface or abstract class. Some people feel that all design should be done via an interface contract and suggest an interface for every type of class, but I don't know if you have to go that far.
回答2:
You might consider moving in a totally different direction and having the objects themselves decide what kind of action to take. For example, the GridObject interface might specify function declarations for handleRightClick(), handleLeftClick(), etc. What you'd be saying in that case is "any class who calls themselves a GridObject needs to specify what happens when they are right-clicked".
So, within the Building class, you might implement handleRightClick to do nothing (or to return an error). Within the ReceptionDesk class, you would implement handleRightClick to rotate the desk.
Your code snippet would then become:
currentBuilding.handleRightClick(... any necessary parameters ...);
回答3:
You are correct to be worried. A good rule of thumb for Object-oriented design is that whenever you use a construct like if(x instanceof Y)
or if(x.getClass().equals(Y.class))
, you should start thinking about moving methods up or down, or extracting new methods.
Elliot and John have both presented good ideas on very different directions you could go, but they're both right in that you should definitely move in some direction. Object oriented design is there to help your code become more legible by making branching for different sorts of behaviors more implicit. Examining what sort of object you're looking at and determining what to do based on that can defeat the purpose of using object-oriented design.
I should also warn you that an interface isn't exactly an empty class. There are some significant differences between empty, abstract classes with abstract methods and interfaces. Instead of thinking of an interface as an empty class, think of an interface as a contract. By implementing an interface, your class promises to provide each of the methods listed in the interface.
来源:https://stackoverflow.com/questions/736081/would-this-be-the-correct-place-to-use-the-java-keyword-interface