I have the following HashMap:
HashMap<Integer, Object> ItemsData = new HashMap<Integer, Object>();
In the HashMap, I have objects of various classes, such as
- ClassOne
- ClassTwo
- ClassThree
Each class has its own methods, attributes etc. How do I refer to proper method, depending on the instance of the class?
For example:
ItemsData.get(5).bark()
-> because item 5 is instance of class 1 which has method barkItemsData.get(2).jump()
-> because item 2 is instance of class 2 which has method jumpItemsData.get(6).fire()
-> because item 6 is instance of class 3 which has method fire
CodePudding user response:
Generally having such an untyped map in the first place is a code smell. You didn't explain enough of the underlying problem you're trying to solve to give you good advice on a nicer solution; merely to point out that this solution probably is severely suboptimal.
If you insist on using it, you can use instanceof
to check if a value is of a certain type, and use a cast operator to treat it as a certain type:
Map<Integer, Object> badIdea = new ....;
...
Object secondValue = badIdea.get(1);
if (secondValue instanceof Dog) {
Dog dog = (Dog) secondValue;
dog.bark();
}
CodePudding user response:
Create an interface, eg:
interface Actor {
void act();
}
And keep a collection of those:
Map<Integer, Actor> ItemsData = new HashMap<>();
Have your classes implement Actor
, either directly:
public ClassOne implements Actor {
public void act() {
// make a barking noise
}
// other fields and methods
}
or indirectly:
public ClassOne implements Actor {
public void act() {
bark();
}
public void bark() {
// make a barking noise
}
// other fields and methods
}
Then invoke Actor's method instead of the original specific method:
itemsData.get(5).act();
You can also invoke all conveniently:
itemsData.forEach(Actor::act);
For a full discussion of this idea, read Liskov substitution principle.