prev | TOC | next

Anatomy of a Class File

files: BouncingTurtle.java (help)


Previously we said that a class serves as a "blueprint" from which objects are constructed.  When you program using an object-oriented language, you create class files describing the classes you design. Let's take a look at the different parts of a class file.  Here is an example file for the class BouncingTurtle.

1.  /**
2.   *  The BouncingTurtle class moves and bounces off the sides
3.   *  of the Display.
4.   *
5.   */
6.  import java.awt.*;
7.  import com.otherwise.jurtle.*;
8. 
9.  public class BouncingTurtle extends Turtle
10. {
11.     static final int TOTAL_MOVES = 400000; // Total number of moves before quitting.
12. 
13.     int bounces;                           // Number of bounces off the walls.

14.
15.     /**
16.      * Entry point to the Turtle's code. 
17.      */
18.     public void runTurtle()
19.     {
20.         setHeading( 30 );
21.         int numMoves = 0;
22.         while ( numMoves < TOTAL_MOVES )
23.         {
24.             move();
25.             numMoves = numMoves + 1;
26.         }
27.     }
28.
29.
30.     private void move()
31.     {
32.         // Move the turtle
33.         forward( 20 );
34.

35.         // Get current location.  If we have hit a wall then turn.
36.         Point pt = getPosition();
37.         Dimension size = getDisplaySize();
38.

39.         if ( pt.y < 0 || pt.y > size.height )
40.         {
41.             setHeading( 180 - getHeading() );
42.             numBounces = numBounces + 1;
43.         }
44.         if ( pt.x < 0 || pt.x > size.width )
45.         {
46.             setHeading( 360 - getHeading() );
47.             numBounces = numBounces + 1;
48.         }
49.

50.     }
51.

52.
53. }

Class comment

Lines 1 - 5 are the class comment that should be at the top of every class file.  The comment should say a few words about what the class does and how to use it.   You may also put other information here such as creation date, author's name and copyright statement.

Import statements

Lines 6 and 7 contain import statements.  These lines specify which other classes or packages (code libraries) your class is going to use.  Line 6 says we are going to use the classes in the standard java.awt package and line 7 indicates we will be using classes in the com.otherwise.jurtle package.

The import statements must be near the beginning of the file, before any class definitions.  They begin with the reserved word import followed by either a specific class name or a package name with the wildcard asterisk (*).  For example, to import the class java.util.Random you would type:

import java.util.Random;

To import all the classes in the java.util package you would type:

import java.util.*;

Some Java programmers believe you should always explicitly specify the classes you will be using and that you should never use the wildcard form of the statement.  This does have the disadvantage, in many cases, of yielding a long list of import statements to maintain.  Because of this, in most of the example code in Jurtle, we will use the simpler wildcard form.  There is no significant penalty for importing classes that are never used.

Class declaration

Line 9 contains the class declaration.

public class BouncingTurtle extends Turtle
         
At a minimum, the class declaration must contain the keyword class followed by a class name.  Class names must be legal Java identifiers.  This means they should start with a letter and contain only letters, numbers, or the connecting underscore character "_".  There is an additional convention in Java that class names should always start with an uppercase character (e.g. BouncingTurtle rather than bouncingTurtle).

Specifying the superclass

As discussed in Lesson 3: A Bit About Objects, all Java objects are part of an inheritance hierarchy and all ultimately are derived from the class Object.  When you declare a class, you must specify which class is its immediate superclass.  You do this using the extends keyword, followed by the name of its superclass.  Thus, if you were creating the class Dog, you might specify that its superclass is Mammal as follows:

class Dog extends Mammal
{
    ...
}


In the class declaration on  line 9 above, we see that BouncingTurtle is a kind of Turtle.  It extends or adds on to the behavior of the Turtle class.  Most of the classes you will create in Jurtle will be subclasses of Turtle.

Access modifiers

What about the word public on line 9 above?  This is a modifier that specifies how the class may be used.  Modifiers are optional.  Here are the basic ones we will be using:
 

Modifier

Meaning

<none>

The class may be used only by other classes in the same package (code library).

public

The class may be used by any class, even if in another package.



Usually when declaring a class the public modifier is used.  The BouncingTurtle code will be run from Jurtle code which resides in the com.otherwise.jurtle package.  Because of this we must specify the BouncingTurtle class as public so Jurtle can use it.

The class body

After the class declaration comes the class body.  In BouncingTurtle this is the code from the opening curly brace on line 10 until the closing curly brace on line 51.  The class body generally contains declarations of member variables (i.e. instance and static variables) and methods.  These declarations must be between the opening and closing curly braces that follow the class declaration.

Declaring member variables

Member variables are declared within the opening and closing braces of the class body and outside of any method declarations for the class.  Typically they are declared as the first thing in the class body, but they don't have to be.  Some programmers put all their variable declarations at the end of the class body.

Member variables fall into two groups: instance variables and static variables.  Their declaration is identical except that static variables are prefaced by the keyword static

Instance variables hold data which is unique for each object instance.  Each instance has its own copy of the variable.  For example, if we created a Human class, we might have an instance variable called name.  As we created instances of the class, we would assign each instance a name which would be held in the name variable.

Static variables should be thought of as belonging to the class as a whole.  Every instance that accesses a given static variable will see the same data because there is only a single copy of it.  For example, the Human class could have a static variable called populationCount that holds the number of instances currently in existence.

In the declaration you give the variable a name and you specify the type of data the variable will hold.  You can also add an optional access modifier.  The minimal declaration looks like:

type name

where type is the data type of the variable and name is the name you will use to refer to the variable.

The allowable access modifiers are:

Modifier

Meaning

<none>

The variable may be accessed only by other classes in the same package (code library).

public

The variable may be accessed by any class, even if in another package.

private

The variable may be accessed only from within this class.

protected

The variable may be accessed only by other classes in the same package and by their subclasses.



For both instance and static variables, you can add the keyword final before the variable name to specify the variable's value can't be changed after the initial assignment.  This effectively makes it a constant.  Be sure not to confuse the static keyword with final.  It is the latter keyword that ensures a variable is non-changing.

On lines 11 and 13 of the BouncingTurtle file, we declare two member variables:

11.     static final int TOTAL_MOVES = 400000; // Total number of turtle moves before quiting.
12.
13.     int numBounces;                   // Number of bounces off the walls.


On line 11 we declare a static variable called TOTAL_MOVES to be of type int and and use the assignment operator "=" to give it an initial value of 400000.  We have used the keyword final to make this variable a constant.  Such variables are often written in all capitals as shown.  The static keyword marks it as a static variable rather than a member variable.  Because this is a static variable, there is only one copy that will be shared among all instances of BouncingTurtle that might be created.

On line 13 we declare an instance variable numBounces which holds a count of the total number of bounces off the sides of the display.  Normally we would initialize this to a value of 0, but in this case we don't need to.  Any uninitialized member variables are automatically set to 0 (for number data types), nil (for object references), or false (for booleans).  On lines 42 and 47 we increment this variable when the turtle reflects off a side.

Method declarations

We will discuss method declarations in more detail in Lesson 12: Methods - Creation and Use.  Here you should just notice that the two methods defined in the BouncingTurtle class, runTurtle() and move(), are declared inside the class body, one after the other.  You cannot declare methods outside of the class body (after the final closing curly brace), nor can you declare a method within the body of another method declaration.

Also be aware that the order of the method declarations is unimportant to the execution of the code.  The sequence in which statements are executed in the program is unrelated to the ordering of the methods.  See Lesson 5: Flow of Execution for more details on this.

Exercises

Look over some of the Turtle classes in the Examples folder in the directory where Jurtle is installed.  Try to identify in these classes the various parts described above.