Reputation: 3750
I need to create enums for countries and states.
What's the most appropriate way to create and relate these enums (as in country X can have states P, Q, R and so on)?
If I have a generic class parameterized with a Country type, can I declare a method which will accept a State only available to the specific country?
For example something like:
public abstract class TestClass <T extends Country> {
public void addState(T.State state);
public List<T.State> getSelectedStates();
}
Edit 1: For easier maintenance, I would prefer to have a separate State enum for each Country as opposed to a single State enum with hundreds of states of all countries. Please comment.
Edit 2: I used the following solution for a problem very similar to this.
Solution: As @Bohemian suggested,
interface Country { }
interface State<T extends Country> { }
public class Countries {
public static class USA implements Country { }
public static class India implements Country { }
}
enum UsaStateEnum implements State<Countries.USA> {
NY, MA, MD, CA
}
enum IndiaStateEnum implements State<Countries.India> {
DEL, BLR
}
class GenericClass<T extends Country> {
List<State<T>> states;
public void addState(State<T> state) {
if (states == null) {
states = new ArrayList<State<T>>();
}
states.add(state);
}
public List<State<T>> getSelectedStates() {
return states;
}
}
public class NestedEnumTest {
public static void main(String[] args) {
GenericClass<Countries.USA> obj = new GenericClass<Countries.USA>();
obj.addState(UsaStateEnum.MA);
// obj.addState(IndiaStateEnum.DEL); // NOT ALLOWED
List<State<Countries.USA>> states = obj.getSelectedStates();
}
}
Upvotes: 1
Views: 464
Reputation: 425033
To answer part 1, you can define two enums, one of which references the other, like this:
public enum State {
A, B, C, D, E
}
public enum Country {
USA(State.A, State.B),
UK(State.C, State.D);
private final List<State> states;
Country(State... states) {
this.states = Arrays.asList(states);
}
public List<State> getStates() {
return states;
}
}
To answer part 2, "no" - there is no way to restrict instances of a particular class to a subset.
You could if you defined a separate class for each country and a separate enum for the states it has, but this doesn't seem like a good idea.
Upvotes: 1
Reputation: 30528
You can make an enum implement an interface like this:
public enum MyEnum implements MyInterface<MyType> {
// ...
}
Apart from implementing interfaces enum
s do not support inheritance yet but if you wish to have common functionality in your enum
s you can always compose for example some strategy object into them.
Upvotes: 1