public
keyword without
understanding it for quite a while. Now we'll get into it a
bit. Every method (aka function) or data member is tagged as
either public
, private
or protected
. We're not ready to
discuss protected
, but understanding the other
two is easy. Here's the rule:
Anything markedSo that's the mechanics of public/private in a nutshell. But what's the purpose of using this?private
is not visible/accessible outside of the class. Anything markedpublic
is visible/accessible outside of the class.
The prototype/body distinction in functions isn't enough to
really separate interface from implementation in functions
(or structs for that matter). Classes
are aggregations of many data and function members.
Some are part of the interface, i.e. are what you want the
user of the class to worry about, some are just part of the
implementation. The public/private
mechanism
is there to allow us to explicitly label members as part of
the interface (public
) or part of the
implementation (private
). In fact, in OOP we
usually only allow member functions to
be public
, i.e. part of the interface. The
reason is, the data members you choose are inherently an
implementation decision. If you make them part of the
interface, you will not be completely free to change the
implementation of your class later ... you'd always have to
keep those data members around. So, we arrive at the
follwing:
A class's interface consists of its public methods (public member functions). In fact, the interface really only consists of the prototypes (aka signatures) of the class's public methods ... and maybe a bit of documentation.The beauty of this is that if you keep this interface the same, you can completely change anything and everything about the implementation, and any program relying on the class should work just the same as always. Once again, the compiler actually enforces this separation of interface vs. implementation; it's not merely a conceptual distinction. If you try to access something marked private from outside a class ... the compiler won't allow it!
Card.java |
import java.util.*; public class Card { //-- PRIVATE MEMBERS ----------------------------------------// // A Card is represented by two indices: an index into the array // faces, and an index into the array suits. int faceIndex; int suitIndex; private static char[] faces = {'2','3','4','5','6','7','8','9','1','J','Q','K','A'}; private static char[] suits = {'C','D','H','S'}; private Card(int f, int s) { faceIndex = f; suitIndex = s; } //-- PUBLIC MEMBERS -----------------------------------------// public Card(String s) { faceIndex = 0; while(faceIndex < 13 && faces[faceIndex] != s.charAt(0)) ++faceIndex; suitIndex = 0; while(suitIndex < 4 && suits[suitIndex] != s.charAt(s.length() - 1)) ++suitIndex; } public String toString() { char f = faces[faceIndex]; char s = suits[suitIndex]; return f == '1' ? "10"+s : " " + f + s; } public Card nextHigherCard() { int s = (suitIndex+1)%4; int f = s == 0 ? faceIndex+1 : faceIndex; return f < 13 ? new Card(f,s) : null; } public int compareFace(Card c) { return faceIndex < c.faceIndex ? -1 : (faceIndex > c.faceIndex ? 1 : 0); } // This just tests the class by producing all cards from 2C up with lower // face value than JH. public static void main(String[] args) { Card c = new Card("JH"); Card d = new Card("2C"); while(d.compareFace(c) == -1) { System.out.println(d); d = d.nextHigherCard(); } } } |
Pile.java |
import java.util.*; public class Pile { //-- PRIVATE MEMBERS -----------------------// private Card [] A; private int n; private static Random generator = new Random(); //-- PUBLIC MEMBERS ------------------------// public Pile() { A = new Card[52]; n = 0; } public void add(Card c) { A[n++] = c; } public Card pullTopCard() { --n; return A[n]; } public Card pullRandomCard() { int i = generator.nextInt(n); Card c = A[i]; --n; A[i] = A[n]; A[n] = c; return c; } public static Pile makeDeck() { Pile P = new Pile(); P.A[0] = new Card("2C"); while(++P.n < 52) P.A[P.n] = P.A[P.n-1].nextHigherCard(); return P; } public void shuffle() { int i = n; while(n > 0) pullRandomCard(); n = i; } public String toString() { String s = ""; for(int i = 0; i < n; ++i) s = s + A[i] + " "; return s; } // This just tests the basic Pile functionality. public static void main(String[] args) { // make deck and shuffle Pile P = makeDeck(); System.out.println(P); P.shuffle(); System.out.println(P); // deal two "hands" Pile H1 = new Pile(); Pile H2 = new Pile(); for(int i = 0; i < 5; ++i) { H1.add(P.pullTopCard()); H2.add(P.pullTopCard()); } System.out.println("Hand 1: " + H1); System.out.println("Hand 2: " + H2); } } |