Как я могу избежать instanceof, когда поведение функции зависит от типа? - PullRequest
1 голос
/ 25 марта 2020

Я занимаюсь разработкой базового c игрового движка. У меня есть абстрактный класс GameObject, который наследуется двумя классами Player и Bullet. Я пытаюсь справиться со столкновением двух игровых объектов. Если оба сталкивающихся объекта одинаковы, ничего не происходит. Если один из них является маркером, а другой игрок, здоровье игрока установлено на 0. Вот фрагмент, показывающий требуемый метод и определения классов:

public interface GameObject {
    void onCollision(GameObject gameObject);
}

public class GameObjectImpl implements GameObject {
    ...
    // By default, do nothing.
    @Override
    public void onCollision(GameObject object) {}    
}


public class Player extends GameObjectImpl {
   ...
   @Override
   public void onCollision(GameObject gameObject) {
      if (gameObject instanceof Player) {
          // Do nothing
      } else if (gameObject instanceof Bullet) {
          this.health = 0;
      }
   }
}

Я хочу избежать instanceof, но я мог бы не придумать способ сделать это. Я хотел реализовать это с использованием polymorphism, поскольку клиенты с интерфейсом GameObject не должны знать подробности о пулях или проигрывателях и т. Д. c. Он просто вызовет метод onCollision для объектов в каждом кадре. Как я могу добиться этого с более чистым кодом? Спасибо.

1 Ответ

1 голос
/ 25 марта 2020

Это может показаться громоздким, поскольку механизм разрешения целевых методов в Javas-коде не самый лучший, но вы можете попробовать что-то похожее на

public class Player extends GameObjectImpl {
   ...
    @Override
    public void onCollision(GameObject gameObject) {
        gameObject.collideWith(this);
    }
}

, а затем расширить GameObject с помощью соответствующего «обратного вызова»:

public interface GameObject {
    void onCollision(GameObject gameObject);
    void collideWith(Player player);
}

, а затем

public class Player extends GameObjectImpl {
   ...
    @Override
    public void onCollision(GameObject gameObject) {
        gameObject.collideWith(this);
    }

    @Override
    public void collideWith(Player player) {
        // ... do nothing, shouldn't happen
    }
}

и

public class Bullet extends GameObjectImpl {
   ...
    @Override
    public void onCollision(GameObject gameObject) {
        gameObject.collideWith(this);
    }

    @Override
    public void collideWith(Player player) {
        player.setHealth(0);
    }
}

Для дальнейшего чтения вы можете выполнить поиск шаблона посетителя в Java.

...