// 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]); } }
like pointers.
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 either by assignment (sharing) of an existing object or of a new constructor (as above)
Note that if x and y refer to objects then x==y iff x and y refer to the same object (i.e., doesn't matter whether their fields are the same).
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 self.m(...) or just m(...) (self is assumed)
Similarly, can write self.suit or just suit to get access to an instance variable.
More interestingly, can send self as a parameter to another object.
Card[] deck = new Card[52];Creates 52 slots for cards, but all are currently null. Does not call Card constructor!
In program had to initialize individual slots:
deck[3] = new Card(TWO,DIAMONDS);
This invokes Card constructor.
Protected: Features accessible within methods of the class (or extensions), but not accessible outside of the object.
All fields should be protected.
Thus firstCard.suit and firstCard.getSuitString() are undefined since both features declared to be protected.
Core Java tends to prefer private to protected. We'll generally use protected.
Private fields are not visible in extensions or outside object.
Protected and private declarations are used to hide implementation details from clients.
Makes it easier to change implementation later if needed.
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;
In equals only call with another CardInterface object, but type of parameter forced to be Object.
If cast is incorrect then program halts with error message.
Ratio gives another example of a class - fractions, this time.