Reputation: 3743
Consider this enum which I want to use as a state machine:
public enum PositionFSM {
State1 {
@Override
PositionFSM processFoo() {
return State2;
}
},
State2 {
@Override
PositionFSM processFoo() {
return State1;
}
};
abstract PositionFSM processFoo();
abstract PositionFSM processBar();
PositionFSM processBar() {
return this;
}
}
The goal is to avoid that all states must implement all events for which they do nothing but return the current state.
In this example a call for processBar
should be ignored by State1
and State2
.
I'm referring to this answer, but the enum given will not compile(Java 1.8). Is there a way for doing it the way I want?
Upvotes: 1
Views: 316
Reputation: 8116
This one does compile:
ublic enum PositionFSM {
State1 {
@Override
PositionFSM processFoo() {
return State2;
}
},
State2 {
@Override
PositionFSM processFoo() {
return State1;
}
};
abstract PositionFSM processFoo();
PositionFSM processBar() {
return this;
}
}
The processBar()
method was declared twice.
EDIT>
An alternative for Java 8 might be to use an interface with default methods, like this:
public interface IPositionFSM {
default IPositionFSM processFoo() {
return this;
}
default IPositionFSM processBar() {
return this;
}
}
public enum PositionFSM implements IPositionFSM {
State1 {
@Override
public IPositionFSM processFoo() {
return State2;
}
},
State2 {
@Override
public IPositionFSM processBar() {
return State1;
}
};
}
Upvotes: 1
Reputation: 2415
You need to define the enum variables first, then the method (I don't know why the linked answer does it the other way around, that never worked in java). Plus don't make the method abstract, so you can provide a default implementation:
public enum State
{
State1
{
@Override
public State process()
{
return State2;
}
},
State2,
State3;
public State process()
{
return this;
}
}
To test it:
System.out.println(State.State1.process());
System.out.println(State.State2.process());
System.out.println(State.State3.process());
Produces the following output:
State2
State2
State3
Upvotes: 2
Reputation: 5220
This code does not compile because the processBar() is declared twice. Just remove the line
abstract PositionFSM processBar();
and code will compile.
Upvotes: 1
Reputation: 6414
Just comment the line
abstract PositionFSM processBar();
Because anyway you have given the implementation in your enum class.
PositionFSM processBar() {
return this;
}
Then you can access your enum's both method like below
PositionFSM.State1.processFoo(); //valid no syntax error
PositionFSM.State1.processBar();
If needed you can override the processBar method for any constant like shown below
State2 {
@Override
PositionFSM processFoo() {
return State1;
}
@Override
PositionFSM processBar(){
return this;
}
};
Upvotes: 3