Как сделать виртуальные статические методы или функциональный эквивалент с отражением в Java - PullRequest
1 голос
/ 03 июня 2011

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

По сути, у меня есть разные типы оружия, которые стреляют по разным схемам, такие как двойное связанное, переменное или просто одно оружие, а также ряд различных снарядов, таких как ракеты, пули, снайперские пули.

Синтаксис в настоящее время имеет вид:

public Bomber() {
    weapons.add(new TwinLinkedWeapon<Missile>(Missile.class));
    weapons.add(new Weapon<Bullet>(Bullet.class));
}

и оружие выглядит так:

public class Weapon<T extends Projectile> {
    long lastShot;
    protected Constructor<? extends T> ctor;

    public Weapon(Class<? extends T> projectileType) {
        try {
            ctor = projectileType.getDeclaredConstructor(actor.Actor.class);
        } catch (SecurityException e) {
            e.printStackTrace();
            return;
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            return;
        }
        lastShot = 0;
    }

    protected long getLastShotTime() {
        return lastShot;
    }

    protected T newProjectile(actor.Actor ship){
        T projectile = null;
        try {
            projectile = ctor.newInstance(ship);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        return projectile;
    }

    protected void setLastShotTime(long time) {
        lastShot = time;
    }

    public void shoot(Actor ship) {
        //calculates time passed in milliseconds
        if((System.currentTimeMillis() - getLastShotTime()) > T.getShotCoolDown()) {
            game.Game.getActors().add(newProjectile(ship));
            setLastShotTime(System.currentTimeMillis());
        }
    }

    public String getWeaponName(){
        return "" + getClass().getName() + " " + ctor.getName();
    }
}

Моя проблема довольно проста для понимания. На линии if((System.currentTimeMillis() - getLastShotTime()) > T.getShotCoolDown())

T является абстрактным классом Projectile вместо производного класса, такого как Bullet или Missile, поэтому, когда я вызываю статический метод T.getShotDelay(), он всегда вызывает Projectile.getShotDelay() вместо производного класса.

Мое единственное решение - создать экземпляр T с помощью ctor и сделать так, чтобы этот атрибут основывался на экземплярах, а не на классах, но это выглядит как «не идеальное» решение.

Я новичок в Java-рефлексии и не уверен в синтаксисе для достижения этой цели. Буду признателен за любой вклад.

Ответы [ 2 ]

3 голосов
/ 03 июня 2011

Вы можете получить статические методы из Class объектов и вызывать их на null, не нужно вызывать конструкторы.Просто возьмите класс времени выполнения T, то есть:

T t = something;
Class<?> tClass = t.getClass();
Method staticMethod = tClass.getMethod("methodName");
staticMethod.invoke(null); // Static methods can be invoked on null.
2 голосов
/ 03 июня 2011

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

Возможно, вам следует рассмотреть возможность использования абстрактного фабричного шаблона .

Вы можете иметь интерфейс IProjectileFactoryэто реализуется MissileFactory и BulletFactory.Фабрики могут создавать новые снаряды Missile и Bullet, которые реализуют интерфейс IProjectile.Фабрики снарядов задаются в качестве параметров при создании новых экземпляров оружия (например, new TwinLinkedWeapon(new MissileFactory())).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...