/* * T05n05.java -- Writing our own interfaces. * * In the previous example, we used Java's Comparable interface, which * of course we didn't have to write. But we could write it, very * easily. This example replaces Java's Comparable with a new interface, * McComparable. See below for more info about it. * * Apart from the interface switch, this is the same code used in * the previous example. */ import java.io.*; /* McComparable: Our new replacement interface for Comparable. * When defining an interface for Java 1.5 and later, we * need to specify that it is parameterized by adding the "" * at the end of the interface name. (Typically in Java, * just a T is used instead of the name Type, but I want its * purpose to be clear.) When a programmer writes a class that * implements this interface, s/he will specify a real class * the will be used in place of the Type placeholder. When * writing the interface, we simply use Type anywhere the * name of the real class would be used, such as in the argument * list of compareTo(). */ interface McComparable { public int compareTo (Type object); } class PlayingCard implements McComparable { char suit; // 'C', 'D', 'H', or 'S' int rank; // 2, 3, ..., 9, 10, 11 (J), 12 (Q), 13 (K), 14 (A) PlayingCard () { rank = (int)Math.floor(Math.random()*13) + 2; // 0-12 + 2 = 2-14 assert (rank>1)&&(rank<15); // verify that the rank is in range switch ((int)Math.floor(Math.random()*4)) { case 0: suit = 'C'; case 1: suit = 'D'; case 2: suit = 'H'; case 3: suit = 'S'; default: suit = '#'; } } PlayingCard (char fromSuit) { rank = (int)Math.floor(Math.random()*13) + 2; // 0-12 + 2 = 2-14 suit = fromSuit; } PlayingCard (int fromRank, char fromSuit) { suit = fromSuit; rank = fromRank; } public int getRank() { return rank; } public char getSuit() { return suit; } public String toString() { String temp = ""; if (rank < 11) temp += rank; else switch (rank) { case 11: temp += "Jack"; break; case 12: temp += "Queen"; break; case 13: temp += "King"; break; case 14: temp += "Ace"; } temp += " of "; switch (suit) { case 'C': temp += "Clubs"; break; case 'D': temp += "Diamonds"; break; case 'H': temp += "Hearts"; break; case 'S': temp += "Spades"; } return temp; } // Note that with the ... implements McComparable // at the top, we have told Java to what we'll be comparing // PlayingCard objects: Other PlayingCard objects! Java // no longer must fall back on the default Object assumption, // and as a result we no longer have to write compareTo() to // accept an Object and cast it before we can use it. We can // accept PlayingCard objects specifically, and simply use them. public int compareTo (PlayingCard card) { if ( (suit == card.getSuit()) && (rank == card.getRank()) ) return 0; if (rank < card.getRank()) return -1; if ( (rank == card.getRank()) && (suit < card.getSuit()) ) return -1; return 1; } } public class T05n05 { public static void compareThem(PlayingCard card1, PlayingCard card2) { if (card1.compareTo(card2) < 0) System.out.println(card1 + " is less than " + card2); else if (card1.compareTo(card2) > 0) { System.out.println(card1 + " is greater than " + card2); } else { System.out.println(card1 + " is equal to " + card2); } } public static void main (String [] args) { int limit, powerOf2; PlayingCard card1 = new PlayingCard(14,'D'), card2 = new PlayingCard(6,'S'), card3 = new PlayingCard(14,'S'), card4 = new PlayingCard(13,'D'), card5 = new PlayingCard(6,'S'); compareThem(card1,card2); // diff. objects, diff. suits, diff. ranks compareThem(card2,card1); // diff. objects, diff. suits, diff. ranks compareThem(card1,card3); // diff. objects, diff. suits, same ranks compareThem(card4,card1); // diff. objects, same suits, diff. ranks compareThem(card2,card5); // diff. objects, same suits, same ranks compareThem(card2,card2); // same object! } }