如何实现强制子类实现枚举的Java接口?
如何让Java接口实现类拥有自定义的枚举选项子集?
我之前碰到这么个场景:想定义一个Abstraction接口,要求所有实现它的类都得有自己的Actions枚举,但最开始的写法根本行不通——接口里定义的枚举没法强制实现类去重写或者自定义:
public interface Abstraction { public enum Actions { } }
比如我写了两个实现类,各自有不同的Actions枚举:
public class AbstractionA implements Abstraction { public enum Actions { f, c, r, a } } public class AbstractionB implements Abstraction { public enum Actions { f, c, b, r, a } }
我本来想通过接口引用实例,直接访问对应类的枚举值,比如:
Abstraction abs = new AbstractionA(); abs.Actions.r; // 这显然做不到,因为接口里的Actions是空的,而且实现类的枚举是各自独立的
后来我琢磨出一个可行的方案,既能统一管理所有可能的Action选项,又能让每个实现类只暴露自己的可用子集:
改进后的接口定义
把所有可能的Action选项都定义在接口的Actions枚举里,同时加一个方法让实现类返回自己支持的动作数组:
public interface Abstraction { public enum Actions { f, c, b, r, s, a } Actions[] availableActions(); }
实现类的写法
每个实现类只需要重写availableActions()方法,返回自己支持的枚举值即可:
public class AbstractionA implements Abstraction{ @Override public Actions[] availableActions() { return new Actions[] {Actions.f, Actions.c, Actions.r, Actions.a}; } } public class AbstractionB implements Abstraction{ @Override public Actions[] availableActions() { return new Actions[] {Actions.f, Actions.c, Actions.b, Actions.r, Actions.a}; } }
方案优势
- 统一枚举池:所有可能的Action都在接口的枚举里定义,避免了多个实现类重复定义相同枚举值的问题
- 灵活子集控制:每个实现类可以自由选择自己支持的动作子集
- 可校验性:如果需要判断某个Action是否是当前实例支持的,直接遍历
availableActions()返回的数组就行,还可以在接口里加个默认方法来简化判断:
public interface Abstraction { public enum Actions { f, c, b, r, s, a } Actions[] availableActions(); default boolean isActionAvailable(Actions action) { return Arrays.asList(availableActions()).contains(action); } }
这样使用的时候,就可以通过接口实例调用isActionAvailable()来校验动作是否合法,完美满足不同实现类拥有不同枚举子集的需求。
内容的提问来源于stack exchange,提问作者Steve W
相关产品推荐
相关产品推荐

