枚举在抽象类中

时间:2016-09-14 09:07:23

标签: java enums abstract

我试图弄清楚如何在不同的类中使用枚举来扩展一个共同的抽象类。

简单示例:

卡类

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

摘要DECK类

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();
    }

Class BriscolaDeck

public class CarteBriscolaDeck extends Deck {
   private enum SUITS{
        COPPE,
        DENARE,
        BASTONI,
        SPADE
    }

    private enum VALUES{
        ASSO,
        DUE,
        TRE,
        QUATTRO,
        CINQUE,
        SEI,
        SETTE,
        FANTE,
        CAVALLO,
        RE
    }

    public CarteBriscolaDeck(){
        super(VALUES,SUITS);
    }
}

PokerDeck班级

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

我做得对吗?是否可以优化?

提前谢谢。

5 个答案:

答案 0 :(得分:2)

您不能在基类中声明enum被子类覆盖,因为enum总是隐式final。此外,子类'enum不能扩展任意类型,它们总是隐式扩展java.lang.Enum

您可以做的是在子类“interface将实现的基类中声明enum。但是,由于您没有在枚举中指定可以抽象的任何功能,因此没有必要(尚)。另一种方法是为子类指定类型参数,子类将用它们的实际类型填充。

要修复的另一件事是在String类中使用“suite”和“value”类型而不是Card,因为使用字符串会破坏使用{{1 }}第

E.g。

enum

答案 1 :(得分:0)

这并不容易。您在子类中声明了全新的类型;所以没有隐含的&#34;覆盖&#34;正如你所希望的那样。 你看,你的基类构造函数有两个类型为Deck.SUITS的枚举,...所以传入一个类型为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()){
    ...
}

然后,在您的子类中:

public class PokerDeck extends Deck<PokerDeck.POKERSUITES, PokerDeck.POKERVALUES> {
  enum POKERSUITS { SPADES, ..
  enum POKERVALUES { ...

  @Override 
  protected List<POKERSUITS> getSuiteEnum() { 
    return list with POKERSUITES.values()); 

请注意:这是更多&#34;伪代码&#34;样式;所以请原谅错别字等。为了让PokerDeck.P​​OKERSUITS工作,那个内部的枚举也不能私有。而且:我选择在这里使用抽象方法,因为它们有助于Open/Closed principle

所以,长话短说:是的,这可以使用在子类中声明的枚举来完成。但老实说;我没有看到在那里使用枚举的附加价值。你可能也有:

abstract protected List<String> getSuiteNames();

并在每个子类中轻松实现:

return Arrays.asList("SPADES", "

答案 2 :(得分:0)

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

答案 3 :(得分:0)

你可以在你的枚举中有一个带有标志的构造函数,并将相关值传递给super方法。可以使用SUIT_TYPS.ONE或SUIT_TYPES.TWO

完成过滤
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
}

答案 4 :(得分:-2)

在Desk构造函数中:

public Desk(Object[] values, Object[] suits)

在子课程中:

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