Item 34: Emulate extensible enums with interfaces

1.  For the most part, extensibility of enums turns out to be a bad idea. It is confusing that elements of an extension type are instances of the base type and not vice versa. There is no good way to enumerate over all of the elements of a base type and its extension.

 

2.  There is at least one compelling use case for extensible enumerated types, which is operation codes. An opcode is an enumerated type whose elements represent operations on some machine. Sometimes it is desirable to let the users of an API provide their own operations, effectively extending the set of operations provided by the API. The basic idea is to take advantage of the fact that enum types can implement arbitrary interfaces by defining an interface for the opcode type and an enum that is the standard implementation of the interface. You can define another enum type that implements this interface and use instances of this new type in place of the base type.

 

3.  Not only is it possible to pass a single instance of an “extension enum” anywhere a “base enum” is expected; it is possible to pass in an entire extension enum type and use its elements in addition to or instead of those of the base type:

public static void main(String[] args) {
    double x = Double.parseDouble(args[0]);
    double y = Double.parseDouble(args[1]);
    test(ExtendedOperation.class, x, y);
}
private static <T extends Enum<T> & Operation> void test(
  Class<T> opSet, double x, double y) {
    for (Operation op : opSet.getEnumConstants())
        System.out.printf("%f %s %f = %f%n", x, op, y, op.apply(x, y));
}

 

A less complex and more flexible way is :

public static void main(String[] args) {
    double x = Double.parseDouble(args[0]);
    double y = Double.parseDouble(args[1]);
    test(Arrays.asList(ExtendedOperation.values()), x, y);
}
private static void test(Collection<? extends Operation> opSet, double x, double y) 
{
    for (Operation op : opSet)
        System.out.printf("%f %s %f = %f%n", x, op, y, op.apply(x, y));
}

 

It allows the caller to combine operations from multiple implementation types.

 

你可能感兴趣的:(enum,extensible)