Home > Software design >  Use different methods depending of the instance of the class
Use different methods depending of the instance of the class

Time:11-23

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 bark
  • ItemsData.get(2).jump() -> because item 2 is instance of class 2 which has method jump
  • ItemsData.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.

  •  Tags:  
  • java
  • Related