Как передать переменные в объект после того, как он был создан с помощью вызова super()?

TLDR: я передаю данные для создания моба. Часть этого процесса создания экземпляров включает в себя создание ИИ для моба. Я хочу, чтобы данные, передаваемые мобом, передавались в ИИ для моба. Это сложно из-за принудительного вызова Super() среди прочего.

История: я создаю свою собственную версию Monsters внутри игры.

Я сам кодировал PathFinder (цели AI, которые сущности используют для навигации по миру). Затем я взял существующего моба (в данном случае корову), стер его нормальный ИИ и заменил его своим собственным: PathFinderGoalRpgMeleeAttack.

Я хотел бы создать новые экземпляры моей коровы (например, RpgCow rpgCow = new rpgCow (урон, отбрасывание)).

Проблема в том, что когда я создаю новый моб (который расширяет другой класс, помните), я вынужден вызывать super(). Супер метод вызывает метод r() (который я переопределяю, чтобы добавить свой собственный ИИ). Поскольку super () вызывает r(), значения повреждений и отбрасывания по-прежнему равны 0,0 и 0,0 (значения java по умолчанию для double), поскольку урон и отбрасывание еще не были установлены.

Любые мысли о том, как я могу обойти это и вставить данные, которые я передаю в создание коровы в создание PathFinder?

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

РЕДАКТИРОВАТЬ, потому что я думаю, что я не был так ясен: проблема в том, что значения Damage и Knockback по-прежнему равны 0, когда я передаю их в PathFinder, что означает позже, когда я делаю this.getDamage в моем pathFinder, независимо от того, что значения, которые я передал в моб при создании урона и отбрасывании всегда будут равны 0.

Код:

public class RpgCow extends EntityCow
{
    private double damage;
    private double knockback;

    public RpgCow(World world, double damage, double knockback)
    {
        super(world);
        this.damage = damage;
        this.knockback = knockback;
        this.bukkitEntity = new CraftRpgCow(this.world.getServer(), this);
    }

    @Override
    protected void r()
    {
        this.goalSelector.a(3,new PathFinderGoalRpgMeleeAttack(this,damage,knockback));
    }

    private static class CraftRpgCow extends CraftCow
    {

        private CraftRpgCow(CraftServer server, EntityCow parent)
        {
            super(server, parent);
        }

    }
}

1 ответ

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

Это, вероятно, лучшее решение, чем вызов r() в конструкторе дочернего класса (RpgCow) после вызова super(), который, в зависимости от вашей реализации, должен перезаписать `cow.goalselector', который был установлен в вашем super() вызов.

Это потребует от вас, чтобы суперкласс был абстрактным, но поскольку вы программируете игру с сущностями / мобами, наличие абстрактного базового класса - это функциональность, которую вы, вероятно, в любом случае захотите.

РЕДАКТИРОВАТЬ: Другой способ сделать это - передать ИИ, который вы хотите, в конструктор суперкласса и в r(), и, если он нулевой, выполнить функциональность базового класса, иначе назначить новый ИИ. Интерфейсы были бы удобным способом полиморфизировать объекты ИИ.

Другие вопросы по тегам