Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cyclic inheritance when implementing inner interface in enum

I have the following implementation that gives a compiler error:

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

It gives a cyclic inheritance error on the first line involving FusionStat.

I don't exactly see what is going on. I had first implemented an abstract class and wanted to let the enum extend that, until I realized that enums cannot extend classes. Now I try to (ab)use the default methods in Java 8.

I am interested in the thought process about why my code does not compile, I was trying to remove code duplication (still have to do so), by pulling the duplicated code inside safeCreateBuilder.

like image 818
skiwi Avatar asked May 22 '14 16:05

skiwi


People also ask

Can an enum inherit from an interface?

Java Enum and Interface As we have learned, we cannot inherit enum classes in Java. However, enum classes can implement interfaces.

What is cyclic inheritance?

Cyclic inheritance occurs at outer class A and inner class InnerB because they attempt to inherit from themselves. As for class C, cyclic inheritance occurs at outer class because it inherits from its inner class.

Does enum support inheritance Java?

Enum . Because a class can only extend one parent (see Declaring Classes), the Java language does not support multiple inheritance of state (see Multiple Inheritance of State, Implementation, and Type), and therefore an enum cannot extend anything else.

Is enum inheritance?

Inheritance Is Not Allowed for Enums.


1 Answers

This would be because you are implementing (coding) the interface you are implementing (inheriting) inside of the class that is inheriting from that class.

I wish I could make that sentence better...

But here is a visual example.

Class A implements Interface B {      Interface B {     } } 

As far as I know, this is not allowed. You need to define the interface outside of the class (in this case, an Enum).

Like so:

Interface B { }  Class A implements Interface B { } 

Best practice is probably to break them up into different files.

like image 99
QuestionMarcs Avatar answered Sep 20 '22 21:09

QuestionMarcs