The coding of non-trivial methods often involves the use of auxiliary methods called ``help'' methods. The specified operation may be easily derivable from another operation that has a simpler definition. For example, in the preceding definition of the composite class hierarchy IntList, we introduced a help method toStringHelp to help support the printing of lists in the same format that Scheme uses. The toStringHelp prints the rest of a non-empty list with a leading blank before each element but no trailing blanks or closing parenthesis.
Since help methods are defined strictly for the use of code within the class, we would like to prevent the definition from ``leaking'' outside the class. Java provides a mechanism for preventing such leaks. Class members can be assigned one of four visibility levels private, default, protected or public. private members are visible only within the class in which they are defined. Default members are visible only within the package in which they are defined. protected members are visible in the package in which they are defined and in subclasses of the defining class. public members are visible everywhere.
We have avoided mentioning the Java package system until now because it is not helpful in writing programs of modest size. Large Java programs typically are partitioned into packages analogous to the file directories in a tree-structure file system. Every Java class belongs to some package. If a source file does not mention a package name, then it is considered part of a special ``empty'' package with no name. In this monograph, we will use the empty package for all of the code that we write. On the other hand, all of the Java core library code that we will use resides in named packages. The Java libraries are partitioned into packages like java.util, java.awt, java.awt.event and javax.swing. As you can see package names themselves can be segmented. Packages are not nestable. There is no connection between java.awt and java.awt.event other than a common name prefix.
The private attribute is well-suited to hiding help methods that aren't required in subclasses. The protected attribute is useful when help methods are referenced in subclasses residing in other packages. In our example above, toStringHelp is accessed by all of the subclasses of IntList. Hence, the appropriate protection mechanism for our toStringHelp is either default or protected. Since all our program classes reside in the same package, it doesn't matter.
When an inherited method is overridden, it cannot be made less visible. Hence, an overridden public method must be declared as public. On the other hand, an overridden protected method may be declared as public.
Finger Exercise Load the sample IntList2 program into the DrJava Definitions window. Convert the test method to a private method. Confirm that the main method for the IntList class still executes the test suite for the sum method. In the Interactions window, try evaluating the following sequence of statements:
IntList l = new Cons(17, new Cons(13, Empty.only)); l.test(30);