An attempt to extend an enum to prevent branching without violating the Open-Closed principle
It's really hard to tell which parts of your code are the problem you are trying to solve, and which parts are the example.  I think that's a hint that the solution has made things worse, rather than better.

Attempting to summarize your constraint - you want to use an enum to select the appropriate behavior to use at some point in the code, but you don't want to use a switch statement, and you don't want to have to modify the enum to achieve the new behavior.

If so, I think an EnumMap should serve nicely.

private static final EnumMap&lt;MyEnum, TwoArgFunction&lt;Integer,Integer,Integer&gt;&gt; lookup = new EnumMap&lt;MyEnum, TwoArgFunction&gt; (MyEnum.class);

static {
    lookup.put(MyEnum.FOO, new TwoArgFunction&lt;Integer,Integer,Integer&gt; () {
        Integer apply (Integer lhs, Integer rhs) {
            return lhs.intValue() - rhs.intValue();
        }
    ) ;

    lookup.put(MyEnum.BAR, new TwoArgFunction&lt;Integer,Integer,Integer&gt; () {
        Integer apply (Integer lhs, Integer rhs) {
            return lhs.intValue() + rhs.intValue();
        }
    ) ;
}

public static class SomeObject {
    ...
    public int doMath(int value) {
        return lookup.get(type).apply(value, param);
    }
}


If you really want to use a visitor based approach, you should probably refactor the abstract methods to an interface; which would allow you to extend the existing vocabulary of enums without actually needing to change MyEnum at all.

interface Visitable {
    public abstract &lt;R, A&gt; R visit(OneEnumVisitor&lt;R, A&gt; visitor, A args);
    public abstract &lt;R, A, B&gt; R visit(TwoEnumVisitor&lt;R, A, B&gt; visitor, A argOne, B argTwo);
}

public static enum MyEnum implements Visitable {
    FOO { ... },
    BAR { ... };
}

public static class SomeObject {
    private final Visitable&lt;Integer,Integer,Integer&gt; type;
    private final int param;

    public SomeObject(Visitable&lt;Integer,Integer,Integer&gt; type, int param) {
        this.type = type;
        this.param = param;
    }

    public int doMath(int value) {
          return type.visit(NewMethod.INSTANCE, value, param);
    }
}


Which in turn allows other programmers to introduce their own enums that can be used by SomeObject

public static enum HisEnum implements Visitable {
    BAZ {...}
}