当前位置: 首页 > 知识库问答 >
问题:

在枚举中实现内部接口时的循环继承

金赤岩
2023-03-14

我的以下实现会导致编译器错误:

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

它在涉及FusionStat的第一行上给出了一个循环继承错误。

我不知道到底发生了什么。我首先实现了一个抽象类,并希望让枚举扩展它,直到我意识到枚举不能扩展类。现在我尝试使用Java8中的默认方法。

我对我的代码为什么不能编译的思考过程很感兴趣,我试图通过在safeCreateBuilder中提取重复的代码来消除代码重复(仍然必须这样做)。


共有3个答案

卓宏达
2023-03-14

FusionStat被定义为实现MonsterStatBuilderHelper,但在此枚举中,您尝试声明扩展了MonsterStatBuilder的接口MonsterStatBuilderHelper

我怀疑您想要做的只是在枚举中定义方法createBuilder()

如果您确实想要定义MonsterStatBuilderHelper接口,这需要在类/枚举之外完成。

张高澹
2023-03-14

你可以在这里看到你的代码有什么错误吗?

public enum FusionStat implements MonsterStatBuilderHelper {
   protected interface MonsterStatBuilderHelper extends MonsterStatBuilder {

   }
}

首先,您正在为FusionStat再次为enum执行MonsterStatBuilderHelper,在enum中使用相同名称的接口MonsterStatBuilderHelper编写一次,您已经为顶级enum执行了该接口,所以这就是为什么会出现循环继承错误。

您可以在下面看到一些循环继承示例

//1st example 
class Person extends Person {}  //this is not possible in real world, a Person itself child and parent both ?

//2nd example 
class Human extends Person{}
class Person extends Human{}

注意:循环继承在java中不支持,因为逻辑上它是不可能的。

通沛
2023-03-14

这是因为您正在从该类继承的类内部实现(编码)您正在实现(继承)的接口。

我希望我能把那个句子写得更好...

但是这里有一个直观的例子。

Class A implements Interface B {

    Interface B {
    }
}

据我所知,这是不允许的。您需要在类(在本例中为枚举)之外定义接口。

像这样:

Interface B {
}

Class A implements Interface B {
}

最佳做法可能是将它们分解成不同的文件

 类似资料:
  • 问题内容: 我有一个关于在接口中放置Java枚举的问题。为了使其更清楚,请参见以下代码: 我知道一个接口由带有 空主体 的方法组成。但是,我在这里使用的枚举需要一个构造函数和一个方法来获取关联的值。在此示例中,建议的接口将不仅包含空主体的方法。是否允许这种实现? 我不确定是否应该将枚举类放入接口或实现此接口的类中。 如果将枚举放入实现此接口的类中,则方法public Number getNumbe

  • 我有一个关于在接口中放置Java枚举的问题。为了更清楚,请看下面的代码: 我知道一个接口由带有空主体的方法组成。但是,我在这里使用的枚举需要一个构造函数和一个方法来获取关联的值。在本例中,所建议的接口将不仅仅由具有空主体的方法组成。允许这种实现吗?

  • 问题内容: 我刚刚发现Java允许枚举实现接口。有什么好的用例? 问题答案: 枚举不仅仅代表被动集(例如颜色)。他们可以代表与功能更复杂的对象,所以你可能想进一步功能添加到这些是那么-例如,你可能如接口,等等。支持这些和组件。

  • 有人能告诉我这是为什么吗?

  • 问题内容: 我有: 因此,如果我正确理解循环继承的发生,是因为: 编译器转到 A 并说: “嘿,A实现了BListener,让我们去查找BListener!” 然后,当它尝试找到BListener时,最终到达 B ,它说: “嘿,B侦听器,A所需的B侦听器在B内!但是等待!B的侦听器需要A!我们去寻找AListener!” 然后到达A,重复一次。我说对了吗? 顺便说一下,这个编译错误发生在我的An

  • 有没有更好的办法解决这个问题?