12.1 Card对象

若你不熟悉扑克牌,现在去买一副并访问 https://en.wikipedia.org/wiki/Standard_52-card_deck 正当其时。

一副标准的扑克牌有 52 张,每张扑克牌都为 4 种花色(suit)和 13 个点数(rank)之一。四种花色为黑桃、红心、方块和梅花;13 个点数为 A、2、3、4、5、6、7、8、9、10、J、 Q 和 K。

如果要定义一个表示单张扑克牌的类,这个类显然应包含如下实例变量:ranksuit,但这些实例变量应为什么类型却不那么明显。一种选择是将它们的类型声明为 String,这样实例变量 suit 将包含 "Spade" 这样的字符串,而 rank 将包含 "Queen" 这样的字符串。这种设计存在的一个问题是,比较两张扑克牌的点数或花色将不那么容易。

另一种设计方案是用整数将点数和花色进行编码(encode),这里的“编码”指的并非加密(转换为看不懂的内容),而是在数字序列和要表示的东西之间建立映射。

下面是为花色建立的一种映射:

梅花 12.1 Card对象 - 图1 0

方块 12.1 Card对象 - 图2 1

红心 12.1 Card对象 - 图3 2

黑桃 12.1 Card对象 - 图4 3

这里使用了数学符号 12.1 Card对象 - 图5,旨在明确地指出这些映射并非程序的组成部分。它们是程序设计的一部分,但不会出现在代码中。

花牌与数字的映射关系如下,其他扑克牌对应其点数表示的数字(2~10):

A 12.1 Card对象 - 图6 1

J 12.1 Card对象 - 图7 11

Q 12.1 Card对象 - 图8 12

K 12.1 Card对象 - 图9 13

至此,Card 类的定义类似于下面这样:

  1. public class Card {
  2. private int rank;
  3. private int suit;
  4. public Card(int rank, int suit) {
  5. this.rank = rank;
  6. this.suit = suit;
  7. }
  8. }

实例变量被声明为私有的:可以在这个类中访问,但不能在其他类中访问。

构造函数包含两个对应于实例变量的形参。可用运算符 new 创建 Card 对象:

  1. Card threeOfClubs = new Card(3, 0);

结果为一个引用,指向表示梅花 3 的 Card 对象。