Выберите перегруженный метод с типом параметра подкласса при передаче родительского типа - PullRequest
0 голосов
/ 20 октября 2019

ищу несколько советов по хорошей практике.

Я создаю систему обнаружения столкновений для игры, запрограммированной на Java. Абстрактный родительский класс Collider расширяет несколько классов коллайдеров различной формы. Класс ColliderManager отвечает за последовательное тестирование коллизий между активными экземплярами коллайдера.

Для обнаружения коллизий между коллайдерами разной формы требуются специализированные алгоритмы, поэтому для каждого соответствующего подкласса коллайдера существует отдельный метод обнаружения.

public abstract class Collider {
    public abstract boolean doesCollide(PointCollider other);
    public abstract boolean doesCollide(LineCollider other);
    public abstract boolean doesCollide(BoxCollider other);
    public abstract boolean doesCollide(CircleCollider other);
}

Каждый подкласс реализует эти абстрактные методы с соответствующими алгоритмами обнаружения столкновений.

Экземпляр ColliderManager проходит через активные коллайдеры и пытается столкнуться со всеми другими коллайдерами.

public class ColliderManager{
    private ArrayList<Collider> colliders = new ArrayList<Collider>();

    public void update() {
        for (Collider collider : colliders) {
            for (Collider otherCollider : colliders) {
                if (collider == otherCollider) //Don't collide with self
                    continue;
                if (collider.doesCollide(otherCollider))
                    collider.onCollision();
            }
        }
    }
}

Конечно, это нене работает, потому что класс Collider не содержит методов, которые принимают Collider в качестве аргумента. Если я добавлю doCollide (Collider other), то независимо от того, какие экземпляры подкласса Collider проверяются, он всегда будет вызывать этот метод. Посмотрев вокруг, я обнаружил, что это потому, что типы параметров определяются временем компиляции, а не временем выполнения.

Мне удалось решить эту проблему, изменив метод в родительском классе.

public boolean doesCollide(Collider other) {
    return other.doesCollide(this);
}

Это прекрасно работает, но действительно ли это лучшее решение?

Несколько раз, когда я пытался найти решение, я думал об использовании оператора instanceof, что, очевидно, является признаком того, что существуют фундаментальные проблемы с дизайном моей программы. Итак, это общая проблема? Каковы хорошие решения / редизайн, чтобы избежать такой проблемы?

...