inlusio
inlusio

Reputation: 17

Creating multiple subclass objects

I'm trying to achieve a 'wave' of enemies through a for loop. Basically when a wave object is called it accepts an int that sets the number of enemies in the wave. Each enemy has it's own class that is a subclass of 'Enemy'. What I'm stuck on is how I can go about passing in a second parameter in the wave constructor to set which enemy subclass is created eg 25 'Orcs' created or 13 'Trolls' in one method. Any help will be greatly appreciated.

Upvotes: 0

Views: 393

Answers (2)

Boris the Spider
Boris the Spider

Reputation: 61168

You can use an Enum

public enum EnemyType {
  ORC{
   @override
   public Enemy create() {
    return new Orc();
   }
  },
  TROLL{
   @override
   public Enemy create() {
    return new Troll();
   }
  }...etc;


  public abstract Enemy create();
}

Then pass the relevant enum into your wave method:

public Collection<Enemy> createWave(final int num, final EnemyType enemyType) {
 final Collection<Enemy> enemies = new ArrayList<>(num);
 for(int i=0;i<num;i++) {
  enemies.put(enemyType.create());
 }
 return enemies;
}

If you have lots of differenet enemy types consider a generic factory

public interface EmemyFactory<E extends Enemy> {
 E create();
}

Then create an implementation for each enemy type and store them in the enum instead

public enum EnemyType {
  ORC(new OrcFactory()),
  TROLL(new TrollFactory()),
  ...etc;

  private final EnemyFactory enemyFactory;
  public EnemyType(final EnemyFactory enemyFactory) {
   this.enemyFactory = enemyFactory;
  }

  public Enemy create() {
   return enemyFactory.create();
  }
}

And last and least you could use a little reflection, assuming your Enemies have a noargs constructor:

public Collection<Enemy> createWave(final int num, final Class<? extends Enemy> enemyClass) {
 final Collection<Enemy> enemies = new ArrayList<>(num);
 for(int i=0;i<num;i++) {
  enemies.put(enemyClass.newInstance());
 }
 return enemies;
}

This is messy and prone to runtime errors however...

Upvotes: 0

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

It sounds like you want to create a static factory method of the Enemy class that creates new Enemy objects based on parameter. Something like:

// EnemyType is an enum
public static Enemy createEnemy(EnemyType enemyType) {
   switch (enemyType) {
     case BASIC_MONSTER:
       return new BasicMonster();
     case ORC:
       return new Orc();
     case TROLL:
       return new Troll();
     case ..... // etc...
   }
}

Note, I would use something cleaner for the parameter such as an enum, not an int so as to be sure that the parameter passed in is correct. Otherwise you risk having a nonsense int such as -24232 being passed in.

Upvotes: 1

Related Questions