web-dev-qa-db-fra.com

Héritage cyclique lors de l'implémentation de l'interface interne dans l'énumération

J'ai l'implémentation suivante qui donne une erreur de compilation:

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);
}

Il donne une erreur d'héritage cyclique sur la première ligne involving FusionStat.

Je ne vois pas exactement ce qui se passe. J'avais d'abord implémenté une classe abstraite et je voulais laisser l'enum étendre cela, jusqu'à ce que je réalise que les énumérations ne peuvent pas étendre les classes. Maintenant, j'essaie (ab) d'utiliser les méthodes par défaut dans Java 8.

Je suis intéressé par le processus de réflexion sur la raison pour laquelle mon code ne se compile pas, j'essayais de supprimer la duplication de code (encore à faire), en tirant le code dupliqué à l'intérieur de safeCreateBuilder.

55
skiwi

Ce serait parce que vous implémentez (codez) l'interface que vous implémentez (héritez) à l'intérieur de la classe qui hérite de cette classe.

J'aimerais pouvoir améliorer cette phrase ...

Mais voici un exemple visuel.

Class A implements Interface B {

    Interface B {
    }
}

Pour autant que je sache, cela n'est pas autorisé. Vous devez définir l'interface en dehors de la classe (dans ce cas, un Enum).

Ainsi:

Interface B {
}

Class A implements Interface B {
}

La meilleure pratique consiste probablement à les décomposer en différents fichiers.

122
QuestionMarcs