2015-02-05 370 views
-2

在这个扑克游戏代码中,我试图创建一个Card类。但是,我想使用enum类型,而不是使用constant,因为我听说它更好。唯一的问题是我尝试了很多次,为suitfaceValue分配实例值,它们是int变量到enum类型变量,但它表示不兼容的类型。怎么了?如何将enum变量赋值给一个数值变量? Java

public class Card { 

    final static int MAX_SUITS = 4; 
    final static int MAX_FACE_VALUES = 13; 

    private int suit; 
    private int faceValue; 

    enum Suit {HEARTS, DIAMONDS, SPADES, CLUBS} 
    enum Face {ACE, JACK, QUEEN, KING} 

    public Card(int suit, int faceValue) { 
     this.suit = suit; 
     this.faceValue = faceValue; 
    } 

    public int getSuit() { 
     if (suit == 0) { 
      return suit = Suit.HEARTS; break; 
     else if (suit == 1) 
      return suit = Suit.DIAMONDS; break; 
     else if (suit == 2) 
      return suit = Suit.SPADES; break; 
     else if (suit == 3) 
      return suit = Suit.CLUBS; break; 
    } 

    public int getFaceValue() { 
     if (faceValue == 1) 
      return faceValue = Face.ACE; break; 
     else if (faceValue == 11) 
      return faceValue = Face.JACK; break; 
     else if (faceValue == 12) 
      return faceValue = Face.QUEEN; break; 
     else if (faceValue == 13) 
      return faceValue = Face.KING; break; 
    } 

    public void setFaceValue(int faceValue) { 
     this.faceValue = faceValue; 
    } 

    public void setSuit(int suit) { 
     this.suit = suit; 
    } 

    @Override 
    public String toString() { 
     if (suit > MAX_SUITS || faceValue > MAX_FACE_VALUES) 
      return "invalid entry"; 
     else if((suit < 0 || faceValue < 0)) 
      return "invalid entry"; 
     else 
      return faceValue + " of " + suit; 
    } 
} 
+6

你应该改变你的构造函数从公共卡(int suit,int faceValue){'到'公共卡(suit suit,face faceValue){'... – assylias 2015-02-05 16:21:54

+0

@assylias我说过,将它分配给一个数值变量而不改变它的类型!我希望下一次你能够更好地阅读这个问题,而不是比赛回答和评估。 – askd 2015-02-05 16:31:40

+3

@askd我看了你的问题。我的观点是:你应该尝试完全摆脱整体:使用枚举的整个想法是,你不需要再使用int常量。如果您继续使用整数,那么您并没有使用枚举的全部功能。您可能需要在整数和枚举之间进行转换的唯一场景是,如果您从外部源接收整数,例如数据文件。在这种情况下,在枚举和整数之间可以映射模式,例如通过向枚举中添加一个int构造函数。 – assylias 2015-02-05 17:20:21

回答

3

如何枚举变量分配给一个数值型变量?

你不行。您必须重构并将int(代表诉讼时)的所有用途更改为Suit

2

我犹豫做写这个答案,因为它枚举失败的全部目的,也没有意义创建任何形式的int值和enum常数之间的“映射”的。

只是不这样做。

执行其他人的建议:将int值替换为相应的enum常数。那么你也将不再需要这些丑陋的解决方法与MAX_SUITS

一个(相对)干净实施Card类可以看成的如下:

public class Card { 

    public static void main(String[] args) 
    { 
     Card c0 = new Card(Suit.HEARTS, Face.ACE); 
     Card c1 = new Card(Suit.DIAMONDS, Face.QUEEN); 
     System.out.println(c0); 
     System.out.println(c1); 
    } 

    private final Suit suit; 
    private final Face face; 

    enum Suit {HEARTS, DIAMONDS, SPADES, CLUBS} 
    enum Face {ACE, JACK, QUEEN, KING} 

    public Card(Suit suit, Face face) { 
     this.suit = suit; 
     this.face = face; 
    } 

    public Suit getSuit() { 
     return suit; 
    } 

    public Face getFace() { 
     return face; 
    } 

    @Override 
    public String toString() { 
     return getFace() + " of " + getSuit(); 
    } 
} 

但是,仍然回答这个问题:可以使用内置方法在intenum值之间建立映射。您可以使用Enum#ordinal方法获得int,并使用(隐式)Enum#values方法获取可使用int作为索引访问的常量数组。

所以实施的不建议方式,它可能是这样的:

public class Card { 

    public static void main(String[] args) 
    { 
     Card c0 = new Card(Suit.HEARTS.ordinal(), Face.ACE.ordinal()); 
     Card c1 = new Card(Suit.DIAMONDS.ordinal(), Face.QUEEN.ordinal()); 
     System.out.println(c0); 
     System.out.println(c1); 
    } 

    final static int MAX_SUITS = 4; 
    final static int MAX_FACE_VALUES = 13; 

    private int suit; 
    private int faceValue; 

    enum Suit {HEARTS, DIAMONDS, SPADES, CLUBS} 
    enum Face {ACE, JACK, QUEEN, KING} 

    public Card(int suit, int faceValue) { 
     this.suit = suit; 
     this.faceValue = faceValue; 
    } 

    public int getSuit() { 
     return suit; 
    } 

    public int getFaceValue() { 
     return faceValue; 
    } 

    public Suit getSuitEnum() { 
     return Suit.values()[suit]; 
    } 

    public Face getFaceValueEnum() { 
     return Face.values()[faceValue]; 
    } 

    public void setFaceValue(int faceValue) { 
     this.faceValue = faceValue; 
    } 

    public void setSuit(int suit) { 
     this.suit = suit; 
    } 

    @Override 
    public String toString() { 
     if (suit > MAX_SUITS || faceValue > MAX_FACE_VALUES) 
      return "invalid entry"; 
     else if((suit < 0 || faceValue < 0)) 
      return "invalid entry"; 
     else 
      return getFaceValueEnum() + " of " + getSuitEnum(); 
    } 
} 

编辑:我想的混乱来自于你想存放“面值”作为一个枚举的事实并且仅有的一些的面值的enum常量(而其他值仅为int,从2到10)。要这样说的话:存储面值为枚举可能不是一个好主意......

0

另一种不推荐的方法做你想要什么: (我刚刚写了这个代码的ad-hoc并没有运行它,所以任何错字的道歉):

public enum Suit { 

    HEARTS(1), 
    DIAMONDS(2), 
    SPADES(3), 
    CLUBS(4); 

    private int id = -1; 

    public Suit(int id) { 
    this.id = id; 
    } 

    public int getId() { 
    return id; 
    } 

    public static Suit parse(int suitId) { 
    for(Suit s : values()) { 
     if(s.getId() == suitId) { 
     return s; 
     } 
    } 
    return null; 
    } 
} 



public enum Face { 

    ACE(11), 
    JACK(12), 
    QUEEN(13), 
    KING(14); 

    private int val = -1; 

    public Face(int val) { 
    this.val = val; 
    } 

    public int getVal() { 
    return val; 
    } 

    public static Face parse(int faceVal) { 
    for(Face f : values()) { 
     if(f.getVal() == faceVal) { 
     return f; 
     } 
    } 
    return null; 
    } 
} 


public class Card { 

    final static int MAX_SUITS = 4; 
    final static int MAX_FACE_VALUES = 13; 

    private Suit suit; 
    private Face faceValue; 

    public Card(int suit, int faceValue) { 
     setSuit(suit); 
     setFaceValue(faceValue); 
    } 

    public int getSuit() { 
     return suit.getId(); 
    } 

    public int getFaceValue() { 
     return face.getVal(); 
    } 

    public void setFaceValue(int faceValue) { 
     this.faceValue = Face.parse(faceValue); 
    } 

    public void setSuit(int suit) { 
     this.suit = Suit.parse(suit); 
    } 

    ... 
} 

但你基本上使用enum作为整数存储在这种情况下。卡上的外部参与者基本上只与整数有关,所以使用枚举纯粹是内部的,在这里是没有意义的。

你的getSuit()getFaceValue()初步实现另一点 - 我想你大概意思是在利用一个开关(break的不具备那些if/else产生巨大影响的):

Suit returnVal; 

switch(suit) { 
    case 0: returnVal = Suit.HEARTS; 
      break; 
    case 1: returnVal = Suit.DIAMONDS; 
      break; 
    case 2: returnVal = Suit.SPADES; 
      break; 
    case 3: returnVal = Suit.CLUBS; 
      break; 
    default: returnVal = null; 
      break; 
} 

return returnVal;