Подтвердить что ты не робот

Циклическое наследование при реализации внутреннего интерфейса в перечислении

У меня есть следующая реализация, которая дает ошибку компилятора:

public enum FusionStat implements MonsterStatBuilderHelper {
    ATTACK {
        @Override
        public MonsterCard.MonsterCardBuilder safeCreateBuilder(final MonsterCard baseMonsterCard, final MonsterCard fusedMonsterCard, final FusionCard fusionCard) {
            Objects.requireNonNull(baseMonsterCard);
            Objects.requireNonNull(fusedMonsterCard);
            Objects.requireNonNull(fusionCard);
            if (baseMonsterCard.equals(fusedMonsterCard)) {
                throw new IllegalArgumentException("baseMonsterCard and fusedMonsterCard need to be different");
            }
            return new MonsterCard.MonsterCardBuilder(baseMonsterCard)
                    .attack(baseMonsterCard.getAttack() + (fusionCard.getFusionPower() * fusedMonsterCard.getAttack()));
        }
    },

    HITPOINTS {
        @Override
        public MonsterCard.MonsterCardBuilder safeCreateBuilder(final MonsterCard baseMonsterCard, final MonsterCard fusedMonsterCard, final FusionCard fusionCard) {
            Objects.requireNonNull(baseMonsterCard);
            Objects.requireNonNull(fusedMonsterCard);
            Objects.requireNonNull(fusionCard);
            if (baseMonsterCard.equals(fusedMonsterCard)) {
                throw new IllegalArgumentException("baseMonsterCard and fusedMonsterCard need to be different");
            }
            return new MonsterCard.MonsterCardBuilder(baseMonsterCard)
                    .maximumHitpoints((int)(baseMonsterCard.getMaximumHitpoints() + (fusionCard.getFusionPower() / 100d * fusedMonsterCard.getMaximumHitpoints())))
                    .hitpoints((int)(baseMonsterCard.getHitpoints() + (fusionCard.getFusionPower() / 100d * fusedMonsterCard.getHitpoints())));
        }
    };

    protected interface MonsterStatBuilderHelper extends MonsterStatBuilder {
        default MonsterCard.MonsterCardBuilder safeCreateBuilder(final MonsterCard baseMonsterCard, final MonsterCard fusedMonsterCard, final FusionCard fusionCard) {
            return createBuilder(baseMonsterCard, fusedMonsterCard, fusionCard);
        }
    }
}

@FunctionalInterface
interface MonsterStatBuilder {
    MonsterCard.MonsterCardBuilder createBuilder(final MonsterCard baseMonsterCard, final MonsterCard fusedMonsterCard, final FusionCard fusionCard);
}

Он дает циклическую ошибку наследования в первой строке involving FusionStat.

Я точно не вижу, что происходит. Сначала я реализовал абстрактный класс и хотел, чтобы перечисление расширялось до тех пор, пока я не понял, что перечисления не могут расширять классы. Теперь я пытаюсь (ab) использовать методы по умолчанию в Java 8.

Мне интересен мыслительный процесс о том, почему мой код не компилируется, я пытался удалить дублирование кода (все еще нужно сделать это), потянув дублированный код внутри safeCreateBuilder.

4b9b3361

Ответ 1

Это будет связано с тем, что вы реализуете (кодируете) интерфейс, который вы реализуете (наследуете) внутри класса, наследующего от этого класса.

Жаль, что я не смог сделать это предложение лучше...

Но вот наглядный пример.

Class A implements Interface B {

    Interface B {
    }
}

Насколько я знаю, это запрещено. Вам необходимо определить интерфейс вне класса (в этом случае Enum).

Так же:

Interface B {
}

Class A implements Interface B {
}

Лучшая практика - это, вероятно, разбить их на разные файлы.

Ответ 2

FusionStat определяется как реализация MonsterStatBuilderHelper, но внутри этого перечисления вы пытаетесь объявить интерфейс MonsterStatBuilderHelper, который расширяет MonsterStatBuilder.

Я подозреваю, что вы хотите просто определить метод createBuilder() внутри вашего перечисления.

Если вы действительно хотите определить интерфейс MonsterStatBuilderHelper, это нужно сделать за пределами класса/перечисления.