【问题标题】:Cyclic inheritance when implementing inner interface in enum在枚举中实现内部接口时的循环继承
【发布时间】:2014-07-11 18:58:38
【问题描述】:

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

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 中来删除代码重复(仍然必须这样做)。

【问题讨论】:

    标签: java interface enums


    【解决方案1】:

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

    我希望我能把这句话做得更好......

    但这是一个直观的例子。

    Class A implements Interface B {
    
        Interface B {
        }
    }
    

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

    像这样:

    Interface B {
    }
    
    Class A implements Interface B {
    }
    

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

    【讨论】:

    • 对!在不同的文件中定义你的接口总是好的(在专用包中?)
    • 不能真正理解问题的本质,但我可以确认我也修复了它,在不同的文件中定义接口。谢谢。 +1
    • 这句话很有诗意,但在一行中清楚地解释了。 +1。
    • 所以这在 Java 中是一个完全任意的限制,没有技术依据,对吧?我将其理解为用这种语言创建大量样板的“最佳实践”。
    • 接口类总是静态的(因此不能添加静态限定符)。这应该意味着这不是问题......(但我今天在 Android Studio 中看到了同样的情况)
    【解决方案2】:

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

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

    首先,您在enum 内再次为FusionStat 实现MonsterStatBuilderHelper 枚举,使用同名接口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 不支持循环继承,因为从逻辑上讲这是不可能的。

    【讨论】:

      【解决方案3】:

      FusionStat 被定义为实现MonsterStatBuilderHelper,但是在这个枚举中你尝试声明接口MonsterStatBuilderHelper 扩展MonsterStatBuilder

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

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

      【讨论】:

        猜你喜欢
        • 2019-11-16
        • 2016-05-18
        • 2017-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多