0

I want to add two enemies to the pane, Dragon and Orc. Both of these classes extend a super class called Entity, and I want to create a single method for both these methods. I have tried using List<? extends Sprite> list and List<? super Sprite> list, but it didn't work as I need to both add the object to a list and read it later on when calling the add method.

public void addDragon(List<Dragon> list) { double imageWidth = 0; for(int i = 0; i < 6; i++) { Dragon dragon = new Dragon(); imageWidth = dragon.getWidth(); pane.getChildren().add(dragon); list.add(dragon); } } public void addDragon(List<Orc> list) { double imageWidth = 0; for(int i = 0; i < 6; i++) { Orc orc = new Orc(); imageWidth = orc.getWidth(); pane.getChildren().add(orc); list.add(orc); } } 
4
  • "I have tried using "List list" and "List list" [...]" - I do not comprehend. A remark: instead of List<Dragon> and List<Orc>, you should use List<? super Dragon> and List<? super Orc>, applying the PECS mnemonic Commented May 3, 2018 at 19:04
  • You could use an Interface. Commented May 3, 2018 at 19:05
  • Can you elaborate, Compass? :) Commented May 3, 2018 at 19:08
  • FYI, optimization generally refers to performance tuning. Merging redundant code is not an optimization in that sense. Commented May 3, 2018 at 19:56

4 Answers 4

2

Pass in a Supplier of the type you want to create:

public <T extends Sprite> void addThings(List<? super T> list, Supplier<T> supplier) { 

And then replace the constructor with an invocation of that supplier:

T thing = supplier.get(); imageWidth = thing.getWidth(); pane.getChildren().add(thing); list.add(thing); 

You would invoke this something like:

addThings(listOfDragons, Dragon::new); addThings(listOfOrcs, Orc::new); 
Sign up to request clarification or add additional context in comments.

4 Comments

I think the common supertype is Sprite. But technically the upper bound isn't necessary at all.
@shmosel not even to invoke the width method (don't know why that's done, though...)
No, it probably is necessary. I don't know what I was thinking.
@shmosel well, I've updated it to use Sprite. Thanks.
1

Considering your class Structure is like this

public interface Entity { // abstract methods here } public class Orc implements Entity { //Code here } public class Dragon implements Entity { //Code here } 

now modify your method as below

 public <T extends Entity> void addDragon(List<T> list, Class<T> clazz) throws IllegalAccessException, InstantiationException { double imageWidth = 0; for(int i = 0; i < 6; i++) { T enemy = clazz.newInstance(); imageWidth = enemy.getWidth(); pane.getChildren().add(enemy); list.add(enemy); } } 

Here < T extends Entity > makes your method flexible to be called by passing any class which are implementing Enemies.

3 Comments

This only works iff. T has ha parameterless, accessible constructor.
In which class do i place that particular method? Is public <T extends entity> a new class?
@Yani no, it is a generic method. But from its declaration, the solution of Andy Turner (using List<? super T> list as parameter) is cleaner.
0

Generic might help you

public <T extends Entity> void addEntity(List<T> list, Class<T> clazz) { double imageWidth = 0; for(int i = 0; i < 6; i++) { T entity = clazz.newInstance(); imageWidth = entity.getWidth(); pane.getChildren().add(entity); list.add(entity); } } 

3 Comments

This only works iff. T has ha parameterless, accessible constructor.
@Turing85 it doesn't, because it will throw a checked exception.
@AndyTurner and it is set deprecated =)
0

Add an interface, or add methods to Entity, for the things you need to do to all entities. This would include a factory method to create a new instance of the specific subtype, and getWidth. Call addEnemy with a prototype instance of the type to be added.

public void addEnemy(List<Entity> list,Entity enemy) { double imageWidth = 0; for(int i = 0; i < 6; i++) { Entity someEnemy = enemy.createNewInstance(); imageWidth = someEnemy .getWidth(); pane.getChildren().add(someEnemy ); list.add(someEnemy ); } 

}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.