Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you properly extend/subclass EnumSet in Java?

I've attempted to extend EnumSet to implement Comparable in Eclipse. However, I'm fraught with errors, right from the beginning. Here's what I start with:

package sets;

import java.util.EnumSet;


enum Suits{
    SPADE, DIAMOND, CLUB, HEART;
}

class ExtendedEnumSet extends EnumSet<Suits> implements Comparable<Suits> {

}

(Issue 1) Defining an Explicit Constructor

It immediately informs me: Implicit super constructor EnumSet<Suits>() is undefined for default constructor. Must define an explicit constructor. So, I follow the quick fix and it adds the following constructor:

ExtendedEnumSet(Class<Suits> finalArg0, Enum[] finalArg1) {
    super(finalArg0, finalArg1);
    // TODO Auto-generated constructor stub
}

...where it then informs me: The constructor EnumSet<Suits>(Class<E>, Enum[]) is not visible. I've tried changing the access modifier of both this class and this constructor to no avail.

(Issue 2) Overriding Abstract Methods

The next issue is when I decide to move on and fix the next error Eclipse reports: The type ExtendedEnumSet must implement the inherited abstract method AbstractCollection<Suits>.iterator(). Of course, this is just the tip of the iceberg. I once again employ the quick fix (add unimplemented methods) and it adds the following:

@Override
public int compareTo(Suits finalO) {
    // TODO Auto-generated method stub
    return 0;
}

@Override
void addAll() {
    // TODO Auto-generated method stub

}

@Override
void addRange(Suits finalArg0, Suits finalArg1) {
    // TODO Auto-generated method stub

}

@Override
void complement() {
    // TODO Auto-generated method stub

}

@Override
public Iterator<Suits> iterator() {
    // TODO Auto-generated method stub
    return null;
}

@Override
public int size() {
    // TODO Auto-generated method stub
    return 0;
}

Where it then reports The method addAll() of type ExtendedEnumSet must override or implement a supertype method. It echoes this error for addRange and complement. I'm able to copy the addAll signature from Set: public boolean addAll(Collection<? extends Suits> collection). However, when I try to copy the other method signatures (addRange, complement) from the API docs, they don't seem to exist. I'm at a loss.

I've gone with EnumMap instead, and it works great. EnumSet seems to be impossible. Am I missing something?

like image 302
skia.heliou Avatar asked Feb 13 '23 05:02

skia.heliou


1 Answers

Short answer: EnumSet is not designed to be extended outside of the java.util package.

Long answer: EnumSet has two implementations: MiniEnumSet and HugeEnumSet. The mini one is optimized to use a single long to represent values; the huge one uses multiple longs. These classes are 'hidden' inside the JRE so that calling code does not know the difference. This is why the EnumSet provides many static factory methods to create new instances. It is a common design pattern to prevent the fragile base class antipattern.

The compiler is telling you that you can't call the super constructor of the class because the developers marked it package-private. Thus you would have to package your code under java.util to call it. The same with the other methods you attempted to override.

like image 76
Thorn G Avatar answered Feb 15 '23 11:02

Thorn G