// A playing card interface.
// Advertises all the public features of a card object.
public interface CardInterface{
// "final" is what makes them constants
// "static" shares one copy of the value over all objects
// in class. I.e., all objects get access to same copy
// Constants
static final int CLUBS = 0;
static final int DIAMONDS = 1;
static final int HEARTS = 2;
static final int SPADES = 3;
// No need to start with 0 as first value;
// they need not even be consecutive
static final int TWO = 2;
static final int THREE = 3;
static final int FOUR = 4;
static final int FIVE = 5;
static final int SIX = 6;
static final int SEVEN = 7;
static final int EIGHT = 8;
static final int NINE = 9;
static final int TEN = 10;
static final int JACK = 11;
static final int QUEEN = 12;
static final int KING = 13;
static final int ACE = 14;
// Methods
int getSuit();
int getRank();
}
//-------------------------------------------
Use interface whenever need a type for a variable. Use class when need
a constructor for an object. (If no interface available can use class
for type as well.)
// A playing card implementation
public class Card implements CardInterface
{
// "protected" means other classes can't access them
// (data hiding)
// instance variables
protected int suit; // The suit of card: CLUBS..SPADES
protected int rank; // The rank of the card: TWO..ACE
...
// Methods
public boolean equals(Object other)
// pre: other is a non-null CardInterface
// post: returns true iff this equals other
{
CardInterface otherCard = (CardInterface) other;
// Cast required so can send getSuit & getRank messages.
return (suit == otherCard.getSuit()) &&
(rank == otherCard.getRank());
}
// 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
public int hashCode()
// post: returns hash code for this card
{
return 13*suit + rank - 2;
}
...
// 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
public static void main(String args[])
// Test Card class
{
// 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]);
}
}
Thus if
firstCard = new Card(ACE,SPADES); secondCard = firstCard;Then both refer to the same card. Assignment is sharing!
Objects initially have value null.
Can be given a value by assignment of
Note that if x and y refer to objects then x==y iff x and y refer to the same object.
Generally use equals method if want to know if the contents are the same.
thirdCard = new Card(ACE,SPADES);then thirdCard != firstCard, but thirdCard.equals(firstCard).
Java is garbage collected: When can no longer access an object, space is reclaimed.
An object can send a message to itself by writing this.m(...) or just m(...) ("this" is assumed)
Similarly, can write this.suit or just suit to get access to an instance variable.
More interestingly, can send "this" as a parameter to another object.
Card[] deck = new Card[52];or
CardInterface[] deck = new CardInterface[52];Creates 52 slots for cards, but all are currently null. Does not call Card constructor!
In program, have to initialize individual slots:
deck[3] = new Card(TWO,DIAMONDS);
This invokes Card constructor.
Typically get access through class or interface name, rather than object name:
CardInterface.SPADES, CardInterface.ACE;Final: May not be changed. Used to declare constants:
static final int SPADES = 3;
Ratio gives another example of a class - fractions, this time.