Using an Interface as a super type for Enum classes - problem with accessing Enum-specific methods

180 views Asked by At

I've been attempting to implement an interface in my enums in order to have rules for a simulation I'm making.

I am trying to access enum-methods such as values() and ordinal() (on objects).

However, even with upper-bounding my classes with my interface name, I still cannot access these methods without overriding them in my interface, which won't work.

public interface State{
    public static void setTileSize(int size){
        return;
    }

    public void draw(PApplet app, int x, int y);

    public Object updateState(int[] allNeighbours);

    public int getColour();

}

enum WireWorld implements State{ // WireWorld
    WIRE(new Color(100, 100, 100)) {
        public WireWorld updateState(int[] allNeighbours){
            if (allNeighbours[1] >= 1){
                return TIP;
            }
            return WIRE;
        }
    }, ...
public class Tile<T extends State> {
     public Tile() {
        int enumCount = T.values().length;
    }
}

I'm trying to call the constructor on Tile and it doesn't work.

1

There are 1 answers

0
Alexander Ivanchenko On BEST ANSWER

You need to provide an indication that T extends Enum as it was mentioned by @Slaw in the comments.

We can declare multiple type bound by chaining them using ampersand sign & and since Enum is a class it needs to be mentioned before interface State (see) :

public class Tile<T extends Enum<T> & State>

Assuming that Tile is meant to hold a reference to an enum member of type T and invoke methods like ordinal() and name() on it. Now compiler will allow doing that, since it knows that T extends Enum<T>.

And seems like your intention was to define an instance variable enumCount in the Tile class that will hold a number of enum members. In order to initialize it, you need to provide an instance of Class<T> as a parameter to the constructor. And one of the way to get access to all enum constants Class<T> is through EnumSet.allOf().

public class Tile<T extends Enum<T> & State> {
    private int enumCount;
    private T item;
    
    public Tile(Class<T> enumClass) {
        this.enumCount = EnumSet.allOf(enumClass).size();
    }
    
    public void someMethod() {
        item.ordinal(); // that will compile
        item.name();    // that will compile as well
    }
    
    // ...
}