Циклическое наследование при реализации внутреннего интерфейса в перечислении
У меня есть следующая реализация, которая дает ошибку компилятора:
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
.
Ответы
Ответ 1
Это будет связано с тем, что вы реализуете (кодируете) интерфейс, который вы реализуете (наследуете) внутри класса, наследующего от этого класса.
Жаль, что я не смог сделать это предложение лучше...
Но вот наглядный пример.
Class A implements Interface B {
Interface B {
}
}
Насколько я знаю, это запрещено. Вам необходимо определить интерфейс вне класса (в этом случае Enum).
Так же:
Interface B {
}
Class A implements Interface B {
}
Лучшая практика - это, вероятно, разбить их на разные файлы.
Ответ 2
FusionStat
определяется как реализация MonsterStatBuilderHelper
, но внутри этого перечисления вы пытаетесь объявить интерфейс MonsterStatBuilderHelper
, который расширяет MonsterStatBuilder
.
Я подозреваю, что вы хотите просто определить метод createBuilder()
внутри вашего перечисления.
Если вы действительно хотите определить интерфейс MonsterStatBuilderHelper
, это нужно сделать за пределами класса/перечисления.