MarqueIV MarqueIV - 1 year ago 32
Android Question

What can a Java enum with abstract functions do that a non-abstracting version can't? (i.e. Is there a technical difference, or is it just a pattern?)

Ok, in this answer here on stack, the poster of the answer shows an example of how you can use abstract methods in an enumeration. I'll repeat that answer here for posterity, albeit slightly-modified to better illustrate the basis of my question.

Consider this enum which uses an abstract method:

public enum Vehicle {
CAR {
public String action() { return "DRIVE!"; }
},
TRUCK {
public String action() { return "DRIVE!"; }
},
BUS {
public String action() { return "DRIVE!"; }
},
TRACTOR {
public String action() { return "DRIVE!"; }
},
MOTORCYCLE {
public String action() { return "RIDE!"; }
},
BOAT {
public String action() { return "SAIL!"; }
},
AIRPLANE {
public String action() { return "PILOT!"; }
};

public abstract String action();
}


As you can see, since 'action' is an abstract function, every single element has to define the override via an anonymous subclass of the enum.

Contrast this with this abstract-free, functionally-equal version which even uses the exact same API:

enum Vehicle {
CAR,
TRUCK,
BUS,
TRACTOR,
MOTORCYCLE,
BOAT,
AIRPLANE;

public String action(){
switch(this)
{
case MOTORCYCLE : return "RIDE!";
case BOAT : return "SAIL!";
case AIRPLANE : return "FLY!";
default : return "DRIVE!";
}
}
}


In this example, you only have to specify the specific cases which differ from a default. Plus, it keeps the values in a nice, clean readable list and reduces a ton of extraneous code as well.

Perhaps I'm missing something, but is there a technical benefit of the abstract method approach? What exactly does it give you that the non-abstract version doesn't? Does it have any extra capabilities?


Note: I suspect the actual answer is because it's not really a function of an enum per se, but rather it's because the enum is compiled to a class and a class supports abstract functions.

However, I'm not exactly sure that's correct either because as others have shown, an enum compiles down to a
static final class
which means it can't be subclassed. Perhaps the compiler doesn't add the 'final' when using abstract functions. Not sure as I haven't been able to view generated output so I can't say for sure, but that would make sense.

But specifically for this question, is there anything an enum with an abstract function can do that a non-abstract version can't?

Answer Source

What can a Java enum with abstract functions do that a non-abstracting version without using them can't?

Nothing!

It isn't a question of code ability. It's a question of convenience, code style, and code protection.

You might as well ask: What can an enhanced for-loop do that a regular for-loop can't? Also nothing, but it is a lot more convenient for iterating an Iterable or an array than using the Iterator yourself.

As you showed yourself, you can do the exact same thing using a switch statement, but switch statements are notoriously fragile, i.e. they easily break when changes are made, because it's too easy to forget adding extra case statements when a new value is added.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download