对枚举进行子类化

Jac*_*ack 16 java inheritance enums

有一种简单的方法来创建Java的子类enum吗?

我问这个是因为我喜欢其中10个实现相同的接口,但是它们对于某些方法也有相同的实现,所以我想通过将所有相同的实现放在扩展的中间对象中来重用代码Enum,它也是超类我需要的所有其他人

也许它不像我想的那么简单?

预先感谢

Pét*_*rök 19

你不能这样做,因为语言不允许你.并且出于一个很好的逻辑原因:如果你可以从子类中删除一些枚举值而不添加新的枚举值,那么继承枚举只会有意义.否则你会打破Liskov替代原则.

这简要说明每当预期超类的实例时,子类的每个实例都应该是可接受的.如果在枚举子类中添加新的枚举成员,那么只知道超级枚举的人就不能接受.

有关更多详细信息和可能的替代方案,请参阅我之前的答案.

在你的具体案例中,@ Jason的建议可能会提供一个很好的解决方案(+1给他:-)

更新到@DrainDog的评论

好点,我上面有点草率:-)实施方面你是对的.但是,从逻辑的角度来看,枚举类型由其有效值集完全描述.一般,一个合适的子类是专业化的超类的.换句话说,有效子类实例的集合(应该)始终是超类实例集的集.(每只狗都是动物,但不是每只动物都是狗.)

  • 不完全正确.枚举值在内部是枚举"类"的实例.SubEnum中的值可以很容易地作为SuperEnum传递,您可以在其上调用SuperEnum的所有方法.你只是无法得到一个比较等于它的SuperEnum实例(所有类的身份相等都是如此). (4认同)
  • 请注意,您*可以*创建枚举的匿名子类,如下所示:`enum E {INSTANCE {}}`.`E.INSTANCE.getClass()== E.class`将评估为false.(但我意识到这通常没什么帮助.) (2认同)

Jas*_*n S 11

我问这个是因为我喜欢其中10个实现相同的接口,但它们对某些方法也有相同的实现,所以我想通过将所有相同的实现放在扩展Enum的中间对象中来重用代码,它也是我需要的所有其他人的超类.

如何使用静态助手类?

interface Animal
{
    public void speak();
}

class AnimalHelper
{
    public static void speakHelper(Animal animal) {
        // common methods here
    }
}

enum Dog implements Animal { SCHNAUZER, LABRADOR, ST_BERNARD, DACHSHUND;
    @Override public void speak() {
        AnimalHelper.speakHelper(this);
    }
};

enum Bird implements Animal { OWL, FINCH, DUCK, GOOSE; }
    @Override public void speak() {
        AnimalHelper.speakHelper(this);
    }
};
Run Code Online (Sandbox Code Playgroud)


Mar*_*tin 5

使用Java 8,您可以使用默认方法将共享实现放在接口中。

public class DefaultMethodOnEnumInterface {

    public interface Greeter {

        default public void greet() {
            System.out.println("Hello, world!");
        }
    }

    public enum Greeters implements Greeter {
        A,
        B;
    }

    public static void main(String[] args) {
        Greeters.A.greet();
        Greeters.B.greet();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果需要访问由Enum类实现的方法,则将签名添加到接口:

public interface Greeter {

    default public void greet() {
        System.out.println("Hello, world! This is " + name());
    }

    /**
     * @see Enum#name()
     */
    public String name(); // implemented by Enum
}
Run Code Online (Sandbox Code Playgroud)