Write this information down, along with your name and some version information, in the form of a Java comment. If you follow the javadoc conventions, it'll be easier to generate user-friendly documentation later. For example,
/** Student: represents a student, with contact information and grades. @author Stephen Bloch @version Jan. 19, 2001 */
A behavior is something a class instance can do, or something that can be done to a class instance. Typically, behaviors are carried out the same way for all instances of a given class, and this way doesn't change over time, but it may depend on the values of properties (above). In the next step, they'll turn into methods.
Since you also decided, above, what information the class contains, you can now put this decision into Java syntax by writing instance variable declarations, e.g.
/** name: the student's name. May contain any non-empty string of characters. */ private String name;Note that javadoc won't display these comments if the variable is declared private, but I'll insist that the information be there in any case.
/** Student: represents a student, with contact information and grades @author Stephen Bloch @version Jan. 19, 2001 */ class Student { // instance variable(s) /** name: the student's name. May contain any non-empty string of characters. */ private String name; // testing method(s) public static void test() { System.err.println ("Testing the Student class"); // test cases go here } // constructor(s) // access method(s) // I/O and conversion method(s) // interesting method(s) }
For each of the methods you defined in the previous step, categorize it and put its contract, header, and examples into the appropriate place, e.g.
/** Student: represents a student, with contact information and grades @author Stephen Bloch @version Jan. 19, 2001 */ class Student { // instance variable(s) /** name: the student's name. May contain any non-empty string of characters. */ private String name; // testing method(s) public static void test() { System.err.println ("Testing the Student class"); // test cases go here } // constructor(s) /** Standard constructor, taking a String. Example: new Student ("Joe Schmoe") produces a Student with name "Joe Schmoe". @param theName the name to give the new student */ public Student (String theName) { ... } // access method(s) /** Get the student's name. @return a String for the student's name */ public String getName () { ... } // I/O and conversion method(s) // interesting method(s) }
I recommend writing, before any other methods, a testing method:
/** test: where we put all the standard test cases for the class */ public static void test () { System.err.println ("Testing class-name."); System.err.println (); // test cases go here /* System.err.println ("foo(14) = " + foo(14) + " (should be 9)"); System.err.println ("foo(bar(7)) = " + foo(bar(7)) + " (should be 12)"); */ }This may include both unit testing (testing individual methods, like
foo(14)
) and integration testing
(testing how methods interact with one another, like
foo(bar(7))
).
Unfortunately in Java, you can't compile a program with test cases for
a method you haven't written yet. So I've commented out the test cases
themselves; as we implement each method, we'll uncomment the relevant
test cases.
Choose methods in a "bottom-up" fashion: start with one that doesn't depend on any others, then one that depends on the first, etc.
You should already have lines
in your static void test()
method that create a number of objects of the class, with different
properties, try various individual methods on them, and print the
results. Now start trying
different sequences or combinations of operations
on each object. If each such sequence of operations behaves as
expected, you have reason to believe the class is correct. If not, you
have a defect somewhere: you already have confidence in each method on
its own, so the defect must be an interaction or misunderstanding
between two or more methods (for example, there's a housekeeping chore
to be done, and each method thinks the other is doing it so it doesn't
get done, or both methods do it so it gets done twice).