我尝试在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
。对于addRange
和complement
,它会重复此错误。我能够从Set
: public boolean addAll(Collection<? extends Suits> collection)
复制addAll
签名。然而,当我试图从API文档中复制其他方法签名(addRange
, complement
)时,它们似乎不存在。我很困惑。
我用EnumMap
代替,它工作得很好。EnumSet
似乎是不可能的。我错过什么了吗?
简短的回答:EnumSet
不是为扩展到java.util
包之外而设计的。
长话短说:EnumSet
有两个实现:MiniEnumSet
和HugeEnumSet
。mini被优化为使用单个long
来表示值;大的使用多个long。这些类被"隐藏"在JRE中,因此调用代码不知道它们之间的区别。这就是EnumSet提供许多静态工厂方法来创建新实例的原因。防止脆弱的基类反模式是一种常见的设计模式。
编译器告诉你不能调用类的超构造函数,因为开发人员将其标记为package-private。因此,您必须将代码封装在java.util
下才能调用它。
我猜EnumSet
从来没有被用户定义的类扩展过。查看这个方法的签名:
abstract void addAll();
它是抽象的,但它是包私有的,因此只有同一包中的类才能看到(调用或覆盖)这个方法。
TL;DL:不幸的是,您不能用自己的类扩展EnumSet
,因为这是不可能的。