Reputation: 552
I want to be able to subclass some values in an enum, in order that I don't have to repeat code too much. Is there some way I can do this? Here's an example of what I want to achieve, which Eclipse quickly tells me is an abomination:
public enum Foo {
BAR {
@Override
public void taskA() {
System.out.println("A");
}
@Override
public void taskB() {}
},
BAZ extends BAR {
@Override
public void taskB() {
System.out.println("B");
}
};
public abstract void taskA();
public abstract void taskB();
}
BAR
would have only the implementation of taskA
and an empty taskB
, and BAZ
would have both methods - BAR
's implementation of taskA
, and its own implementation of taskB
.
I'm not changing the values of the enum after it's declared, so why doesn't this work? I could call BAR
's taskA
method within BAZ
, so why can't I do this?
Upvotes: 2
Views: 419
Reputation: 21608
Enum-Constants are objects (instances), not classes. You can only subclass classes.
However even that will not work: you can only extend enums with anynomous inner classes.
You will have to find another solution for your use case. You could:
BAR.taskA()
in BAZBut my favorit is:
Example code:
class Behavior {
public static Runnable A = new Runnable() {
public void run() {
System.out.println("A");
}
}
public static Runnable B = new Runnable() {
public void run() {
System.out.println("B");
}
}
public static Runnable DO_NOTHING = new Runnable() {
public void run() {
}
}
}
public enum Foo {
BAR(Behavior.A, Behavior.DO_NOTHING),
BAZ(Behavior.A, Behavior.B);
private final Runnable mechanismA;
private final Runnable mechanismB;
private Foo(Runnable mechanismA, Runnable mechanismB) {
this.mechanismA = mechanismA;
this.mechanismB = mechanismB;
}
public void taskA() {
mechanismA.run;
}
public void taskB() {
mechanismB.run;
}
}
Pros of this solution:
If you have Java8 available you can even shorten the code to this:
public static Runnable A = () -> {
System.out.println("A");
};
Upvotes: 2
Reputation: 10084
I want to be able to subclass some values in an enum, in order that I don't have to repeat code too much.
The usual way to share code among constant-specific methods is to declare a private static method (either in the enum itself or in a utility helper class) which contains the common code that you wish to access from your constant-specific methods.
For example ...
public enum Foo {
BAR {
@Override
public void taskA() {
commonToTaskAandB();
System.out.println("B");
}
@Override
public void taskB() {}
},
BAZ {
@Override
public void taskB() {
commonToTaskAandB();
System.out.println("B");
}
};
public abstract void taskA();
public abstract void taskB();
private static void commonToTaskAandB() {
// shared code here
:
:
}
}
Note that the code "BAZ extends Bar
" is illegal because BAZ is not a type. BAZ is an instance of your Enum<Foo>
type. An instance cannot extend another type. It is incorrect to apply object-oriented principles like inheritance to enum constants because, in Java, enum constants are instances of a class and not classes themselves.
Upvotes: 2