如何在Java中正确地扩展/子类EnumSet



我尝试在Eclipse中扩展EnumSet以实现Comparable。然而,从一开始,我就充满了错误。下面是我的开头:

package sets;
import java.util.EnumSet;

enum Suits{
    SPADE, DIAMOND, CLUB, HEART;
}
class ExtendedEnumSet extends EnumSet<Suits> implements Comparable<Suits> {
}

(Issue 1)定义显式构造函数

它立即通知我:Implicit super constructor EnumSet<Suits>() is undefined for default constructor. Must define an explicit constructor.所以,我遵循快速修复并添加以下构造函数:

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

…然后它告诉我:The constructor EnumSet<Suits>(Class<E>, Enum[]) is not visible。我已经尝试更改这个类和这个构造函数的访问修饰符,但无济于事。

(Issue 2)重写抽象方法

下一个问题是当我决定继续并修复Eclipse报告的下一个错误:The type ExtendedEnumSet must implement the inherited abstract method AbstractCollection<Suits>.iterator()时。当然,这只是冰山一角。我再次使用快速修复(add unimplemented methods),它添加了以下内容:

@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;
}

然后报告The method addAll() of type ExtendedEnumSet must override or implement a supertype method。对于addRangecomplement,它会重复此错误。我能够从Set: public boolean addAll(Collection<? extends Suits> collection)复制addAll签名。然而,当我试图从API文档中复制其他方法签名(addRange, complement)时,它们似乎不存在。我很困惑。

我用EnumMap代替,它工作得很好。EnumSet似乎是不可能的。我错过什么了吗?

简短的回答:EnumSet不是为扩展到java.util包之外而设计的。

长话短说:EnumSet有两个实现:MiniEnumSetHugeEnumSet。mini被优化为使用单个long来表示值;大的使用多个long。这些类被"隐藏"在JRE中,因此调用代码不知道它们之间的区别。这就是EnumSet提供许多静态工厂方法来创建新实例的原因。防止脆弱的基类反模式是一种常见的设计模式。

编译器告诉你不能调用类的超构造函数,因为开发人员将其标记为package-private。因此,您必须将代码封装在java.util下才能调用它。

我猜EnumSet从来没有被用户定义的类扩展过。查看这个方法的签名:

abstract void addAll();

它是抽象的,但它是包私有的,因此只有同一包中的类才能看到(调用或覆盖)这个方法。

TL;DL:不幸的是,您不能用自己的类扩展EnumSet,因为这是不可能的。

相关内容

  • 没有找到相关文章

最新更新