对枚举进行子类化

是否有一种简单的方法来子类化Java enum

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

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

预先感谢

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

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

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

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

更新到@DrainDog的评论

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

我问这个是因为我喜欢其中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); } }; 

使用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(); } } 

如果需要访问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 } 

尝试使用Apache commons包中的Enums,您可以在其中inheritanceEnums。 不知道这是否会对你有所帮助。

虽然Java中有抽象枚举的提议 ,但其好处被认为太低而不能超过成本。 你必须坚持使用转发方法调用。

该语言不允许您这样做,因为Enums旨在有效地表示枚举值,而不是用于实现代码。 尝试使用其他模式,如静态助手(实用程序)类。

@Jason S提供了一个很好的回复,但静态方法让你失去了OOP的潜力。

代表团怎么样? 我的意思是:

  1. 定义一个公共接口“I_A”,您可以在其中定义所有getter / setter和所有其他方法。

  2. 定义一个“类似结构”的类“S_C”:它只实现getter和setter,其他方法是空的,因为没用。

  3. 为了使您的枚举更短(根据代码行),定义第二个接口“I_A_Delegating”,扩展第一个接口,有一个额外的getter / setter类型“I_A”(它是我们的委托者),并且,由于Java的默认方法,将getter / setter定义为调用委托者的getter / setter。

  4. 您的所有枚举都实现了“I_A_Delegating”并且具有“S_C”的本地实例

代码示例:

 public class EnumFakeExtension{ /**"I_A"*/ public static interface CommonInterface{ public Object getFieldOne(); public Object getFieldTwo(); public void setFieldOne(Object o); public void setFieldTwo(Object o); public void someMethod(); } /*"S_C"*/ public static class CommonDelegator_FieldKeeper implements CommonInterface{ Object oOne, oTwo; public Object getFieldOne(){ return oOne; } public Object getFieldTwo(){ return oTwo; } public void setFieldOne(Object o){ oOne = o; } public void setFieldTwo(Object o){ oTwo = o; } public void someMethod(){ /*empty*/ } } /**"I_A_Delegating"*/ public static interface CommonInterface_Delegating extends CommonInterface{ public CommonInterface getDelegate(); public void setDelegate(CommonInterface delegator); /**Just to simplify*/ public default void setDefaultDelegate(CommonInterface delegator){ setDelegate( new CommonDelegator_FieldKeeper() ); } public default Object getFieldOne(){ return getDelegate().getFieldOne(); } public default Object getFieldTwo(){ return getDelegate().getFieldTwo(); } public default void setFieldOne(Object o){ getDelegate().setFieldOne(o); } public default void setFieldTwo(Object o){ getDelegate().setFieldTwo(o); } } /*the enums, now*/ public static enum EnumFirst implements CommonInterface_Delegating{ FieldA, FieldB, FieldC; EnumFirst (){ setDefaultDelegate(); } final CommonDelegator_FieldKeeper delegator; public CommonInterface getDelegate(){ return delegator; } public void setDelegate(CommonInterface delegator){ this.delegator=delegator; } public void someMethod(){ /*do what You need*/ } } public static enum EnumSecond implements CommonInterface_Delegating{ FieldA, FieldB, FieldC; EnumSecond (){ setDefaultDelegate(); } final CommonDelegator_FieldKeeper delegator; public CommonInterface getDelegate(){ return delegator; } public void setDelegate(CommonInterface delegator){ this.delegator=delegator; } public void someMethod(){ /*do what You need, again*/ } } }