1

So I have two arrays,

Array<GroundEnemy> groundEnemies;
Array<FlyingEnemy> flyingEnemies;

Then I have the methods to render enemies as,

renderGroundEnemy(groundEnemies, delta);
renderFlyingEnemy(flyingEnemies, delta);

and I declared these methods as,

private void renderGroundEnemy(GroundEnemy enemies, delta){ ... }
private void renderFlyingEnemy(FlyingEnemy enemies, delta){ ... }

Because the method for rendering flying enemies is the same for rendering ground enemies I thought I would just reuse the same method. Now I'm confused how to set the argument type for the method. How do I set the argument type for the render method? I was thinking something like this but I still don't quite get it,

private void renderEnemy(ArrayOfObjects enemies, delta){ ... }
r.cam
  • 43
  • 1
  • 7

3 Answers3

4

One idiomatic approach would be to create an interface (or an abstract class) for both GroundEnemy and FlyingEnemy.

For instance:

public interface Enemy { ... }
public class GroundEnemy implements Enemy { ... }
public class FlyingEnemy implements Enemy { ... }

Then you would be able to just use Enemy:

private void renderEnemy(Array<? extends Enemy> enemies, delta) { ... }

The choice of interface vs abstract class is important: interface basically says:

"I have those two things: FlyingEnemy and PublicEnemy, and I want to interact with them in the very same way."

Whereas extending an abstract class means a bit more:

"I have those two things: FlyingEnemy and PublicEnemy, and I want to interact with them in the very same way. They also work quite similarly."

For instance, if both FlyingEnemy and GroundEnemy have properties like stamina, or killed, or methods like .hit() or .heal() - then it might make sense to put all those into an abstract class and not repeat the implementation (the same implementation!) for both enemy types.

See this StackOverflow question and following answers for a pretty good explanation of differences between the concept of an interface and of an abstract class.

Community
  • 1
  • 1
kamituel
  • 34,606
  • 6
  • 81
  • 98
0

One of the advantages of object oriented programming is you can do EXACTLY this. I'm assuming GroundEmenies and FlyingEnemies have more in common than just the rendering process. What convention tells you to do here is create a super class, Enemy, that holds the similarities between Flying and Ground enemies.

Then flying and ground enemies can extend the enemy class.

public class GroundEnemy extends Enemy { ... }
public class FlyingEnemy extends Enemy { ... }

Now, any method that works with properties shared by both types of enemies can use Enemy as a parameter type. Example:

private void renderEnemy(Array<? extends Enemy> enemies, delta) { ... }
Kyle Becker
  • 1,360
  • 12
  • 20
0

The best approach is to create super interface Enemy and specify methods related to both GroudEnemy and FlyingEnemy. The code:

public interface Enemy { 
   public void attack(int damage);
}
public interface GroundEnemy extends Enemy { ... }
public interface FlyingEnemy extends Enemy { ... }

Now both GroudEnemy and FlyingEnemy has method attack.

Jay Smith
  • 2,331
  • 3
  • 16
  • 27