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; // 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; // 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 method contracts, headers, and examples for all the methods that you defined above, then picking one method at a time for filling in templates, filling in bodies, and testing. 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.
I also recommend writing, before any other methods (or at least fairly early), a testing method:
/** test: where we put all the standard test cases for the class */ public static void test () { System.out.println ("Testing class-name."); System.out.println (); }This doesn't do anything interesting yet (except tell you what class you're working on), but as you write each new method, you'll add its test cases to the body of the test method, and you can see whether it works simply by invoking the test method.
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).