4

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?

nikodaemus
  • 1,918
  • 3
  • 21
  • 32
  • 2
    You're probably better off just using a `Comparator>` instead of trying to extend it. – Louis Wasserman Aug 18 '14 at 20:12
  • 1
    Did you mean `implements Comparable>`, or are you trying to compare the suits themselves? If the latter, you should make a class that implements `Comparator`. – Sean Van Gorder Aug 18 '14 at 20:12
  • 1
    Why do you think you need to extend `EnumSet` to implement `Comparable`? What does it mean to compare an `EnumSet` to a `Suits`? Suppose I have a set of `{ SPADE, HEART }` and I compare it to a `Club`? What would `compareTo` return? – David Conrad Aug 18 '14 at 20:12
  • I needed it to be `Comparable` so I could store it in a `TreeSet`. – nikodaemus Aug 18 '14 at 22:44
  • 1
    @skia.heliou: No, you don't. You can pass a `Comparator` into the `TreeSet` constructor; you don't need it to be `Comparable` just to put it in a `TreeSet`. – Louis Wasserman Aug 18 '14 at 23:04
  • @LouisWasserman: So I can. =) I'd only looked as far as the `add(E e)` method. Thanks! – nikodaemus Aug 18 '14 at 23:58

2 Answers2

8

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.

Thorn G
  • 12,620
  • 2
  • 44
  • 56
0

I guess EnumSet was never meant to be extended by user defined classes. Look into the signature of this method:

abstract void addAll();

It is abstract, but it is package-private, thus only classes in the same package can see (call or override) this method.

TL;DL: Unfortunately, you cannot extend EnumSet with your own class because it is not possible.

kajacx
  • 12,361
  • 5
  • 43
  • 70
  • This may have been an issue with the package-private scope and Eclipse, as the original abstract signature ended up needing to be replaced with `public boolean addAll(Collection extends Suits> collection)`. – nikodaemus Aug 18 '14 at 22:47