简体   繁体   中英

Subclass in ArrayList<Superclass> method calling issues

I have an arraylist of entities. The Entity class has

public void update(int delta, Level level, ArrayList<Entity> entities){
    //do stuff
}

a subclass of entity, Player, has a function overriding it

public void update(int delta, Level level, ArrayList<Entity> entities){
    //do player specific stuff
    super.update(delta, level, entities);
}

when I call the player objects update function from an arraylist of entities, like this:

for(Entity entity : entities)            //contains an object of Player
    entity.update(delta, level, entities);

it calls the entity function directly and the player specific stuff doesnt happen, however if I call it like this:

((Player)entities.get(0)).update(delta, level, entities);

it does. I thought I understood the problem but I tried the following code

private static class Foo{
    public void print(){
        System.out.println("I AM FOO");
    }
}
private static class Bar extends Foo{
    public void print(){
        System.out.println("i am bar");
        super.print();
    }
}
public static void main(String[] args){
    ArrayList<Foo> foos = new ArrayList<Foo>();
    foos.add(new Foo());
    foos.add(new Bar());
    for(Foo leFoo: foos)
        leFoo.print();
}

and it actually calls the print function from Bar when the object is a bar. I'm kinda lost at this point.

Since you have multiple Level classes, you have to ensure that the Player.update() method signature references the correct one (in order to override successfully):

public class Player {

  @Override
  public void update(int delta, game.level.Level level, ArrayList<Entity> entities) { ... }
}

The following code works for me:

List<Entity> fooList = new ArrayList<Entity>();
fooList.add(new Entity());
fooList.add(new Player());
for (Entity entity : fooList) {
    entity.update(1, fooList);
}

private static class Entity {
    public void update(int delta, List<Entity> entities) {
        System.out.println("in Entity");
    }
}
private static class Player extends Entity {
    @Override
    public void update(int delta, List<Entity> entities) {
        System.out.println("in Player");
        super.update(delta, entities);
    }
}

Make sure that you need an @Override on the Player.update(...) method. It may be that the signatures are not matching so you aren't actually overriding the method signature you think you are.

Couple of other comments:

  • Typically when we are dealing with lists we pass around List<?> and not the implementation ArrayList<?> .

  • If you are iterating through the entity list and passing it into the method call, you will need to make sure that the update method is not changing the list otherwise you will throw an ConcurrentModificationException .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM