// 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.