我刚刚发现Java允许枚举实现接口。它的一个好的用例是什么?
当前回答
这里一些人给出的可比示例是错误的,因为Enum已经实现了这一点。你甚至不能重写它。
一个更好的例子是有一个定义数据类型的接口。你可以使用枚举来实现简单类型,也可以使用普通类来实现复杂类型:
interface DataType {
// methods here
}
enum SimpleDataType implements DataType {
INTEGER, STRING;
// implement methods
}
class IdentifierDataType implements DataType {
// implement interface and maybe add more specific methods
}
其他回答
我在一个接口中使用了一个内部枚举来描述一个策略来保持实例控制(每个策略都是一个Singleton)。
public interface VectorizeStrategy {
/**
* Keep instance control from here.
*
* Concrete classes constructors should be package private.
*/
enum ConcreteStrategy implements VectorizeStrategy {
DEFAULT (new VectorizeImpl());
private final VectorizeStrategy INSTANCE;
ConcreteStrategy(VectorizeStrategy concreteStrategy) {
INSTANCE = concreteStrategy;
}
@Override
public VectorImageGridIntersections processImage(MarvinImage img) {
return INSTANCE.processImage(img);
}
}
/**
* Should perform edge Detection in order to have lines, that can be vectorized.
*
* @param img An Image suitable for edge detection.
*
* @return the VectorImageGridIntersections representing img's vectors
* intersections with the grids.
*/
VectorImageGridIntersections processImage(MarvinImage img);
}
枚举实现该策略的事实便于允许枚举类充当其所包含的Instance的代理。其中也实现了接口。
它是一种strategyEnumProxy:P,客户端代码看起来像这样:
VectorizeStrategy.ConcreteStrategy.DEFAULT.processImage(img);
如果它没有实现接口,它将是:
VectorizeStrategy.ConcreteStrategy.DEFAULT.getInstance().processImage(img);
枚举不只是表示被动的集合(例如颜色)。它们可以表示具有功能的更复杂的对象,因此你可能想要在这些对象上添加更多的功能——例如,你可能有诸如Printable、Reportable等接口,以及支持这些接口的组件。
另一个可能性:
public enum ConditionsToBeSatisfied implements Predicate<Number> {
IS_NOT_NULL(Objects::nonNull, "Item is null"),
IS_NOT_AN_INTEGER(item -> item instanceof Integer, "Item is not an integer"),
IS_POSITIVE(item -> item instanceof Integer && (Integer) item > 0, "Item is negative");
private final Predicate<Number> predicate;
private final String notSatisfiedLogMessage;
ConditionsToBeSatisfied(final Predicate<Number> predicate, final String notSatisfiedLogMessage) {
this.predicate = predicate;
this.notSatisfiedLogMessage = notSatisfiedLogMessage;
}
@Override
public boolean test(final Number item) {
final boolean isNotValid = predicate.negate().test(item);
if (isNotValid) {
log.warn("Invalid {}. Cause: {}", item, notSatisfiedLogMessage);
}
return predicate.test(item);
}
}
和使用:
Predicate<Number> p = IS_NOT_NULL.and(IS_NOT_AN_INTEGER).and(IS_POSITIVE);
最常见的用法是将两个枚举的值合并到一个组中,并以类似的方式对待它们。例如,查看如何加入水果和蔬菜。
这是我的理由……
我用Enum的值填充了一个JavaFX组合框。我有一个接口,可识别(指定一个方法:identify),它允许我指定任何对象如何为我的应用程序标识自己,以便进行搜索。这个接口使我能够扫描任何类型的对象(对象可能用于标识的任何字段)的列表以进行标识匹配。
我想在我的组合框列表中找到一个匹配的标识值。为了在包含Enum值的组合框上使用此功能,我必须能够在我的Enum中实现可识别接口(碰巧,在Enum的情况下实现是微不足道的)。
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap