Jsevillamol Jsevillamol - 6 months ago 18
Java Question

Overriding an enum in Java

I have a class in Java which has an enum implementing an interface such as

class MyClass{
interface Command{
void execute();
String getId();
}

enum MyCommands implements Command{
aCmd{
void execute(){/*do something*/}
String getId(){return "aCmd";}
}
}

void MyMethod(String s){
for(Command cmd: MyCommands){
if(s.equals(cmd.getId())) cmd.execute();
}
}
}


The class has a method for parsing text, in which I iterate over the enum values and compare the input to the getId() of each command.

Now I do want to extend the class with different commands (that is, I want to extend it in a way that overrides MyCommands and defines new commands). How can I do that?
(I'm open to refactoring the super class in other simple way)

class childClass extends myClass{
//In myMethod this enum should be iterated instead of myCommands
enum childCommands implements Command{
otherCmd{
void execute(){/*do something*/}
String getId(){return "aCmd";}
}
}

Answer

If you want to extend your class it is probably better to create an additional enum e.g. MyExtendedCommands. Then you can create a Set<Command> in that class that contains both the original EnumSet and the extended EnumSet of both MyCommands and MyExtendedCommands.

class MyClass {
    interface Command {
        void execute();

        String getId();
    }

    enum MyCommands implements Command {

        aCmd {
            public void execute() {/* do something */
            }

            public String getId() {
                return "aCmd";
            }
        }
    }

    public void myMethod(String s) {
        for (Command cmd : EnumSet.allOf(MyCommands.class)) {
            if (s.equals(cmd.getId()))
                cmd.execute();
        }
    }
}

can be extended by using:

class MyExtendedClass extends MyClass {

    enum MyExtendedCommands implements Command {

        bCmd {
            public void execute() {/* do something */
            }

            public String getId() {
                return name();
            }
        }
    }

    public void myMethod(String s){
        Set<Command> allCommands = new HashSet<>();
        allCommands.addAll(EnumSet.allOf(MyCommands.class));
        allCommands.addAll(EnumSet.allOf(MyExtendedCommands.class));

        for(Command cmd: allCommands){
            if(s.equals(cmd.getId())) cmd.execute();
        }
    }
}

Obviously this doesn't protect you against duplicates at compile time. But it should be easy to prevent dupes at runtime (e.g. by testing the number of resulting commands in allCommands.

Then again, this is an easy method to override commands as well, so maybe this drawback can be turned into an advantage.

Comments