// A playing card // Implementation (c) 1997 William Lenhart // Annotated with discussion of Java syntax public class Card implements CardInterface { // "protected" means other classes can't access them (data hiding) // instance variables protected int suit; // The suit of the card: CLUBS..SPADES protected int rank; // The rank of the card: TWO..ACE // Constructors // Always have a no-operand constructor // This one merely invokes the two-argument constructor, using "this" syntax // post: Constructs a card with default value "Ace of Spades" public Card() { this(ACE,SPADES); } // This version of the constructor does all of the work // post: Constructs a card of the given type public Card(int theRank, int theSuit) { suit = theSuit; rank = theRank; } // This allows different cards to be checked for equality // For technical reasons, parameter must be of type "Object" // Note: We must "coerce" the type of other to be "Card" // "this" refers to the object invoking the method. // It is not actually necessary here, but emphasizes the fact that we have // two Cards whose instance variables are changing // Note: == is equality test BUT = is assignment // Note: && is logical "and"; || is logical "or" // pre: other is a non-null Card // post: returns true iff this equals other public boolean equals(Object other) { if (other instanceof Card) { Card otherCard = (Card) other; return (this.suit == otherCard.suit) && (this.rank == otherCard.rank); } else { return false; } } // Having this method allows Cards to be used in certain data structures // For now, just try to return different values for different cards // This returns a number in the range 0..51; different cards yield different values // post: returns hash code for this card public int hashCode() { return 13*suit + rank - 2; } // post: returns suit of card public int getSuit() { return suit; } // post: returns rank of card public int getRank() { return rank; } // Java provides a String class with many useful methods // "switch" is Java's "case" statement // It must end each block with "break", or else next block is also executed // It must have "default" block, even if unused // post: returns a string representation of the suit protected String getSuitString() { String suitStr = null; switch (suit) { case CLUBS: suitStr = "Clubs"; break; case DIAMONDS: suitStr = "Diamonds"; break; case HEARTS: suitStr = "Hearts"; break; case SPADES: suitStr = "Spades"; break; default: } return suitStr; } // post: returns a string representation of the rank protected String getRankString() { String rankStr = null; switch (rank) { case TWO: rankStr = "Two"; break; case THREE: rankStr = "Three"; break; case FOUR: rankStr = "Four"; break; case FIVE: rankStr = "Five"; break; case SIX: rankStr = "Six"; break; case SEVEN: rankStr = "Seven"; break; case EIGHT: rankStr = "Eight"; break; case NINE: rankStr = "Nine"; break; case TEN: rankStr = "Ten"; break; case JACK: rankStr = "Jack"; break; case QUEEN: rankStr = "Queen"; break; case KING: rankStr = "King"; break; case ACE: rankStr = "Ace"; break; default: } return rankStr; } // The toString method is special. It allows for automatic printing of Objects // Note: + for String concatenation // post: returns a string representation of this card public String toString() { return getRankString() + " of " + getSuitString(); } // If a class contains a main method, that method can be run when the class is compiled // I always have one, which I use for testing the class // Test Card class public static void main(String args[]) { // Create some cards CardInterface first = new Card(THREE,DIAMONDS); CardInterface second = new Card(); System.out.println(); System.out.println(first); System.out.println(second); System.out.println(); // Note: ! is the negation operator System.out.print("These cards are "); if(!first.equals(second)) System.out.print("not "); System.out.println("equal"); System.out.println(); // Create an array of cards // Note syntax for array declaration CardInterface[] hand = new CardInterface[5]; hand[0] = new Card(ACE,HEARTS); hand[1] = new Card(KING,HEARTS); hand[2] = new Card(QUEEN,HEARTS); hand[3] = new Card(JACK,HEARTS); hand[4] = new Card(TEN,HEARTS); // for loop // Note: declaration in for loop; ++ is the "add 1" operator for(int i=0;i<4;i++) { System.out.print(hand[i] + ", "); } System.out.println(hand[4]); } }