4

I have a general Java question.

I've got different 'spell' classes, they aren't made of 1 object because they differ too much. So I created for example 3 classes:

  1. called Ice ice = new Ice();
  2. called Hurricane hurricane = new Hurricane();
  3. called Bomb bomb = new Bomb();

Those spells do have same corresponding methods (getCooldown(), getName(), cast()).

So I want these class instances to be saved in a certain list/hashmap where I can iterate through. When iterating through the instances I'll check if getName() equals a certain name, and if that's the case return the certain class instance.

I hope this is possible, if not I hope someone can help me thinking of another idea.

Wouter
  • 125
  • 1
  • 9

4 Answers4

7

You can have all three classes implement a common interface and declare the list to contain instances of the interface.

interface Spell {
    int getCooldown();
    String getName();
    void cast();
}

public class Ice implements Spell {
    @Override
    public int getCooldown() { . . . }
    @Override
    public String getName() { . . . }
    @Override
    public void cast() { . . . }
    // more stuff specific to Ice
}
public class Hurricane implements Spell {
    // similar to above
}

Then you can do something like:

List<Spell> spells = new ArrayList<>();

spells.add(new Hurricane());
spells.add(new Ice());

You can also do this with a common base class, but coding to an interface generally provides more flexibility.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • 1
    Regular class inheritance also works in this case, especially if the OP has code in common. Something like a cooldown mechanic ought to not have to be reimplemented. – Radiodef Dec 11 '13 at 18:18
  • 1
    @Radiodef - The typical way to handle that and maintain the benefits of coding to an interface (see [here](http://jdevelopment.nl/java-best-practices-5-code-to-interface-access-by-name-and-instance-data/) and [here](http://stackoverflow.com/questions/3194278/should-you-always-code-to-interfaces-in-java)) is to implement the common operations in a base class that implements the interface. It's a little more coding, but greatly simplifies testing and future evolution of the class structure. – Ted Hopp Dec 11 '13 at 18:21
6

Try implementing an interface or base class that they all derive from, then make a List containing that interface or base class.

Choraimy
  • 166
  • 1
  • 11
  • I have never worked with interfaces do yo have something like a tutorial or example? – Wouter Dec 11 '13 at 18:12
  • @WouterZorgdrager: http://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html – Jeroen Vannevel Dec 11 '13 at 18:12
  • @WouterZorgdrager you can see Ted's answer for an example in using an interface, if the methods on your spells work the same way (at least some of them) it might be better to use an Absract Class, that way you don't have to write the same code multiple times. (Info on abstract classes: http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html) – Choraimy Dec 11 '13 at 18:19
0

Define an interface that has methods getCooldown(), getName(), cast(). Then make all classes implement that interface. Now create a list as follows and add to it :

List<MyInterface> list = new ArrayList<MyInterface>();
fastcodejava
  • 39,895
  • 28
  • 133
  • 186
0

Create a basic abstract class or an interface for all your spells, for exmaple:

public abstract class Spell {

    public abstract int getCooldown();

    public abstract String getName();

    public abstract void cast();
}

Now let your spells extend the Spell class. Then create your List like this:

List<Spell> spells = new ArrayList<>();

Now you can add any Spell to spells list.

Flying Dumpling
  • 1,294
  • 1
  • 11
  • 13
  • An abstract class isn't very useful when you have to override each method anyway. You use it when you want to define common behaviour or provide common implementation. When you just want a common definition, that's when you use an interface. – Jeroen Vannevel Dec 11 '13 at 18:18