Java 抽象类中的枚举

Java 抽象类中的枚举,java,enums,abstract,Java,Enums,Abstract,我试图弄清楚如何在扩展公共抽象类的不同类中使用enum 简单的例子: 卡片类 public class Card { private String name; private String value; private String suit; public Card(String name, String value, String suit) { this.value = value; this.suit= suit;

我试图弄清楚如何在扩展公共抽象类的不同类中使用enum

简单的例子:


卡片类

public class Card {
    private String name;
    private String value;
    private String suit;

   public Card(String name, String value, String suit) {
        this.value = value;
        this.suit= suit;
    }
}

抽象甲板类

public abstract class Deck {
    private enum SUITS{

    }

    private enum VALUES{

    }
    private int cardNumber;
    private ArrayList<Card> cardList;

    public Deck(VALUES valori,SUITS semi){
        ArrayList<Card> clist = new ArrayList<>();
        for (SUITS s: semi.values()){
            for (VALUES v: valori.values()){
                cardList.add(new Card(v.toString(),s.toString()));
            }
        }
        cardNumber = cardList.size();
    }

类扑克牌

public class PokerDeck extends Deck {
   private enum SUITS{
       SPADES,
       HEARTS,
       DIAMONDS,
       CLUBS
   }

    private enum VALUES{
        ACE,
        TWO,
        THRRE,
        FOUR,
        FIVE,
        SIX,
        SEVEN,
        EIGHT,
        NINE,
        TEN,
        JACK,
        QUEEN,
        KING
    }

    public PokerDeck(){
        super(VALUES,SUITS);
    }
}
我做得对吗?有可能优化吗


提前谢谢你。

没那么容易。您正在子类中声明全新的类型;因此,没有你所希望的隐含的“覆盖”。 你看,你的基类构造函数需要两个Deck.suites类型的枚举。。。因此,传入Poker.SUITS类型的枚举无法工作

一种解决方法是使用泛型:

abstract class Deck<S extends Enum<S>, V extends Enum<V>> {
  abstract protected List<S> getSuiteEnums();
  abstract protected List<V> getValuesEnums();

  public Deck(){
    ArrayList<Card> clist = new ArrayList<>();
    for (S s: getSuiteEnums()){
    ...
}

我认为它不合适。我不明白你为什么要在这里使用Enum。 收藏可以做同样的事情,让读者更清楚。

在桌面构造器中:

public Desk(Object[] values, Object[] suits)
在子类中:

public Subclass(){ 
    super(values.values(), suits.values()) 
}

在枚举中可以有一个带标志的构造函数,并将相关值传递给super方法。可以使用西服类型1或西服类型2进行过滤

public enum SUITS {

    COPPE(SUIT_TYPES.ONE.name()),
    DENARE(SUIT_TYPES.ONE.name()),
    BASTONI(SUIT_TYPES.ONE.name()),
    SPADE(SUIT_TYPES.ONE.name()),
    SPADES(SUIT_TYPES.TWO.name()),
    HEARTS(SUIT_TYPES.TWO.name()),
    DIAMONDS(SUIT_TYPES.TWO.name()),
    CLUBS(SUIT_TYPES.TWO.name());

    private final String type;

    SUITS(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }

}

enum SUIT_TYPES {
    ONE, TWO
}

不能在基类中声明要由子类重写的
enum
,因为
enum
s总是隐式地
final
。此外,子类“
enum
s”不能扩展任意类型,它们总是隐式扩展
java.lang.enum

您可以做的是在基类中声明一个
接口
,子类“
enum
将实现该接口。但是,由于您没有在枚举中指定任何可以抽象的功能,所以(目前)这样做没有意义。另一种方法是为基类指定类型参数,子类将用它们的实际类型填充基类

另一个需要解决的问题是,在
Card
类中使用“suite”和“value”类型而不是
String
s,因为在那里使用String会破坏使用
enum
s的全部优势

例如

公共期末成绩卡{
终审法院的诉讼;
最终V值;
公共卡(S套装,V值){
这套衣服;
这个值=值;
}
@凌驾
公共字符串toString(){
返回值+“”+值;
}
}
公务舱甲板{
受保护的最终套装;
保护最终设定值;
受保护的最终清单所有卡片;
公共甲板(类suitType、类valueType){
Set suits=EnumSet.allOf(suitType);
Set values=EnumSet.allOf(valueType);
List cardList=newarraylist(suits.size()*values.size());
适用于(S套房:套装){
对于(V值:值){
卡片列表。添加(新卡(套件、价值));
}
}
allSuits=集合。不可修改集合(suits);
allValues=Collections.unmodifiableSet(值);
allCards=集合。不可修改列表(cardList);
}
@凌驾
公共字符串toString(){
返回getClass().getSimpleName()+所有卡片;
}
}
公共类扑克牌扩展牌组{
enum套装{黑桃、红桃、钻石、梅花}
枚举值{ACE,2,3,4,5,6,7,
八,九,十,杰克,皇后,国王}
公共扑克牌组(){
super(Suits.class、Values.class);
}
}
公共类卡特尔公司
延伸甲板{
enum套装{COPPE、DENARE、BASTONI、SPADE}
枚举值{ASSO、DUE、TRE、QUATTRO、CINQUE、SEI、SETTE、FANTE、CAVALLO、RE}
公共卡特尔公司{
super(Suits.class、Values.class);
}
}

我认为您可能不熟悉枚举的概念,或者您的回答不清楚如何使用数组而不是枚举,在这种情况下,您应该改进它。您没有看到枚举在表示少量预定义值方面的优势吗?比较更快,类型检查更严格。OP的真正问题是,
字段是字符串,而不是那些枚举的实例。可能需要再坐20分钟才能找到一个基于枚举的解决方案,允许在这里使用它们;也适用于子类化的事情。但老实说:我已经在这里呆了很长时间;没有任何“回报”。。。所以,不确定这是否会很快发生。提示:请让我知道我的答案是否适合你;或者如果你还想找别的东西;否则,请考虑接受最佳的答案,以表示“你得到了你所需要的”。你写道:保护最后一套所有的西装;保护最终设定值;和after allSuits=Collections.unmodifiableSet(suits);allValues=Collections.unmodifiableSet(值);是打字错误吗?因为final意味着一个costant。。对吗?
final
字段在构建后不能修改。但是,当然,他们必须在施工期间分配一次。在这里,它发生在构造函数的末尾,在集合被填充之后。检查IDE中的代码是否与此处发布的代码完全相同,以及必须添加的必要的
import
语句。此代码经过测试,在构造函数中分配
最终
字段的能力至关重要。重要的是,它必须在构造函数中,并且必须是一次(每个可能的代码路径)。字段本身不能有初始值设定项。
return Arrays.asList("SPADES", "
public Desk(Object[] values, Object[] suits)
public Subclass(){ 
    super(values.values(), suits.values()) 
}
public enum SUITS {

    COPPE(SUIT_TYPES.ONE.name()),
    DENARE(SUIT_TYPES.ONE.name()),
    BASTONI(SUIT_TYPES.ONE.name()),
    SPADE(SUIT_TYPES.ONE.name()),
    SPADES(SUIT_TYPES.TWO.name()),
    HEARTS(SUIT_TYPES.TWO.name()),
    DIAMONDS(SUIT_TYPES.TWO.name()),
    CLUBS(SUIT_TYPES.TWO.name());

    private final String type;

    SUITS(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }

}

enum SUIT_TYPES {
    ONE, TWO
}
public final class Card<S,V> {
    final S suit;
    final V value;
    public Card(S suit, V value) {
        this.suit = suit;
        this.value = value;
    }
    @Override
    public String toString() {
        return suit+" "+value;
    }
}
public class Deck<S extends Enum<S>,V extends Enum<V>> {
    protected final Set<S> allSuits;
    protected final Set<V> allValues;
    protected final List<Card<S,V>> allCards;

    public Deck(Class<S> suitType, Class<V> valueType) {
        Set<S> suits =EnumSet.allOf(suitType);
        Set<V> values=EnumSet.allOf(valueType);
        List<Card<S,V>> cardList=new ArrayList<>(suits.size()*values.size());
        for(S suite: suits){
            for(V value: values) {
                cardList.add(new Card<>(suite, value));
            }
        }
        allSuits =Collections.unmodifiableSet(suits);
        allValues=Collections.unmodifiableSet(values);
        allCards =Collections.unmodifiableList(cardList);
    }

    @Override
    public String toString() {
        return getClass().getSimpleName()+allCards;
    }
}
public class PokerDeck extends Deck<PokerDeck.Suits,PokerDeck.Values> {
    enum Suits  { SPADES, HEARTS, DIAMONDS, CLUBS }
    enum Values { ACE, TWO, THREE, FOUR, FIVE, SIX, SEVEN,
                  EIGHT, NINE, TEN, JACK, QUEEN, KING }

    public PokerDeck(){
        super(Suits.class, Values.class);
    }
}
public class CarteBriscolaDeck
       extends Deck<CarteBriscolaDeck.Suits,CarteBriscolaDeck.Values> {
    enum Suits  { COPPE, DENARE, BASTONI, SPADE }
    enum Values { ASSO, DUE, TRE, QUATTRO, CINQUE, SEI, SETTE, FANTE, CAVALLO, RE }

    public CarteBriscolaDeck(){
        super(Suits.class, Values.class);
    }
}