我刚刚发现Java允许枚举实现接口。它的一个好的用例是什么?


当前回答

枚举就像Java类,它们可以有构造函数、方法等。唯一不能使用它们的是new EnumName()。实例是在枚举声明中预定义的。

其他回答

它是可扩展性所必需的——如果有人使用您开发的API,则您定义的枚举是静态的;它们不能被添加或修改。但是,如果让它实现一个接口,使用API的人可以使用相同的接口开发自己的枚举。然后,您可以向枚举管理器注册这个枚举,枚举管理器将枚举与标准接口结合在一起。

Edit: @Helper方法有一个完美的例子。考虑让其他库定义新的操作符,然后告诉管理器类“嘿,这个枚举存在——注册它”。否则,您只能在自己的代码中定义操作符——就没有可扩展性了。

对我来说,使用枚举接口的最佳用例之一是谓词过滤器。这是一种非常优雅的方法来弥补apache集合的类型化不足(如果不能使用其他库)。

import java.util.ArrayList;
import java.util.Collection;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;


public class Test {
    public final static String DEFAULT_COMPONENT = "Default";

    enum FilterTest implements Predicate {
        Active(false) {
            @Override
            boolean eval(Test test) {
                return test.active;
            }
        },
        DefaultComponent(true) {
            @Override
            boolean eval(Test test) {
                return DEFAULT_COMPONENT.equals(test.component);
            }
        }

        ;

        private boolean defaultValue;

        private FilterTest(boolean defautValue) {
            this.defaultValue = defautValue;
        }

        abstract boolean eval(Test test);

        public boolean evaluate(Object o) {
            if (o instanceof Test) {
                return eval((Test)o);
            }
            return defaultValue;
        }

    }

    private boolean active = true;
    private String component = DEFAULT_COMPONENT;

    public static void main(String[] args) {
        Collection<Test> tests = new ArrayList<Test>();
        tests.add(new Test());

        CollectionUtils.filter(tests, FilterTest.Active);
    }
}

最常见的用法是将两个枚举的值合并到一个组中,并以类似的方式对待它们。例如,查看如何加入水果和蔬菜。

由于枚举可以实现接口,它们可以用于严格执行单例模式。试着让一个标准类成为单例允许…

获奖理由:可以使用反射技术将私有方法公开为公共方法 用于从你的单例中继承和用其他东西重写你的单例方法

作为单例的枚举有助于防止这些安全问题。这可能是让enum充当类并实现接口的原因之一。只是猜测。

更多讨论请参见https://stackoverflow.com/questions/427902/java-enum-singleton和java中的Singleton类。

枚举就像Java类,它们可以有构造函数、方法等。唯一不能使用它们的是new EnumName()。实例是在枚举声明中预定义的。