views:

107

answers:

5

Assuming I create a method which is passed an object and that method would perform an action depending on the object passed. How should I identify the object?

I thought of using the class name to identify the object, but that may be impractical since I could easily change the class name of objects, and generate headaches during future development. Am I right?

edit: for example, i have objects ball and bomb. if i have another object called wall, and the wall has the method to resolve collisions with the wall (e.g. the coordinates of the colliding ball and bomb) but have different logic depending on the colliding object (i.e. ball and bomb)

A: 

this code will lead you to using switch consider using polymorphism. and this will cancel naming problem automatically.

Andrey
+7  A: 

What you are asking for is the instanceof operator.

if (object instanceof SomeClass) {
  // do something
} else if (object instanceof SomeOtherClass) {
  // do something else
}

However, this is not a good practice. Instead you may use the so called double-dispatch. Make the object that is passed conform to an interface which defines the operation in terms of the other class. So:

public interface ThrowableItem {
   void throwAt(Wall wall);
}

public class Wall {
    void accept(ThrowableItem item) {
        item.throwAt(this);
    }
}

And then provide the appropriate implementations within Ball and Bomb (both of which implement ThrowableItem)

Take a look at the Visitor pattern - you can move the operations to a WallVisitor which knows how to handle the colisions for each object.

Bozho
This is what I was saying in my answer. You went the extra mile and did some code. If you mention abstract classes and which one is a better option, I'll delete my answer!
San Jacinto
edited my question with an example to visualize the question a bit. from what i understand from your code snippet, i should resolve the colliding object's coordinates from a method in the colliding object's class. is this correct?
mixm
@mixim - I updated the names of the classes/interfaces in my example to follow yours
Bozho
@mixm in this instance, the logic should be handled in the ball and bomb classes. Since it's the same exact use-case, just different behavior for each type of class, you'll want to use an abstract class (or implement an interface) as a base and ball and bomb would inherit from it. The abstract method could be called something like collision(). The wall would then call the colliding object's collision() method, and the object should determine what happens.
San Jacinto
Given your updated description I'd suggest you look at http://www.red3d.com/cwr/steer/Containment.html, particularly because of "Communication between vehicles and obstacle is handled by a generic surface protocol: the vehicle asks the obstacle if a given probe point is inside the surface, and if so asks for the nearest point on the surface and the normal at that point. As a result, the steering behavior needs no knowledge of the surface's shape."
ptomli
@Bozho: from your updated example, the object implementing ThrowableItem should contain the method throwAt(object) and implement the logic to resolve the collision?
mixm
@ptomli: from my example, and your ideas, i get that the ball should not know what to do, and should ask the object being collided with the information on how to resolve the collision, without knowing what object it collided with.
mixm
@mixim - yes, the object implements these details. See my update for a slight modification
Bozho
@Bozho: thanks for your answers. haha never thought of implementing it like this. my earlier thoughts at a solution to my problem was compartmentalizing the collision resolution code inside the collidable objects themselves, since it would be easier then to add more collidable objects(since the colliding object would simply ask the object to resolve the coordinates of the colliding object)
mixm
A: 

It depends on what the actions are. How are they related? Is it that you have a number of objects that do the same thing but in slightly different ways? For example, suppose I have a method that is supposed to print a document but I want the same method to print pdf and doc files.

If your situation is similar to that then you may want to consider using inheritance as follows: Create a super class, in my example lets call it Document with a print() method. The print method does not have to do anything. Then create a subclass for each type of document, so I will end up with a PdfDocument and a DocDocument subclass. Each of these will provide an implementation for print() that can print the type of document that it relates to.

Then the method that I write will be:

  public void printDocument(Document d){
        d.print();
  }

That is, by targetting the super class type I do not have to worry about the specific action that each type of document does. That way I avoid code that checks the type of object that is being passed to my method. It makes the code more robust for future extension.

Vincent Ramdhanie
A: 

Depending on the context, you might also want to provide different methods (overloading) for the different possible types that may be passed in.

public void doSomething(TypeA object) {
    // TypeA specific stuff
}
public void doSomething(TypeB object) {
    // TypeB specific stuff
}
ptomli
+2  A: 

You can use instanceof but beware of the pitfalls. It will be 'true` for subclasses as below :

if (subclass instanceof superclss)  // returns true
fastcodejava