Monday, July 09, 2007

More with Java enums: simulating inheritance

One drawback to the Java enum is the lack of inheritance. Java uses inheritance for many reasons, one of which is implementation inheritance. (In C++ you would use private inheritance for the same reason.)

To recapture implementation inheritance with enums, use the visitor pattern:

class Convert {
    public interface Vivid {
        char character();
    }

    public static <E extends Enum<E> & Vivid> E from(
            E[] values, char character) {
        for (E e : values)
            if (e.character() == character)
                return e;

        throw new IllegalArgumentException("Boring: " + character);
    }
}

enum Men implements Convert.Vivid {
    OLIVIER('L'), WAYNE('J');

    private final char character;

    Men(char character) {
        this.character = character;
    }

    public char character() {
        return character;
    }

    public static Men valueOf(char character) {
        return Convert.from(values(), character);
    }
}

The implementation of valueOf(char):Men is handled in Convert and can be reused in other enum classes.