1.5.5 Helper Methods, Packages, and Visibility
Keywords: current

Next: 1.6 Using Classes to Up: 1.5 Basic Program Design Previous: 1.5.4.1 Overriding equals

##
1.5.5 Helper Methods, Packages, and Visibility

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 helper method `toStringHelp` to help support the printing of lists without extraneous blanks. The `toStringHelp` method prints the `rest` of a non-empty list with a leading blank before each element but no trailing blanks or closing parenthesis.

Since helper 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.

In section 1.1.2, we stated that the only way to access the fields of an object is through ``getter'' methods provided by the class definition. If we always declare the instance (non-static) fields of a class as `private`, then this statement is completely accurate. We strongly recommend following this convention; it supports to the object-oriented principle of separating the implementation of a class from its interface.

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. Each package, except for the ``default'' package discussed below, has a unique name consisting of one or more Java identifiers separated by periods. Hence `java`, `java.lang`, and `java.awt.event` are are all valid package names.

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 ``default'' package with no name. In this monograph, we will use the default 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`. 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 helper methods that aren't required in subclasses. The `protected` attribute is useful when helper 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. However, if we wanted to define subclasses of `IntList` in another package, we would need to declare the `toStringHelp` method as `protected` to make it visible within these subclasses.

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 `IntList` program into the DrJava Definitions pane. 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 pane, try evaluating the following sequence of statements:

    IntList l = new Cons(17, new Cons(13, Empty.ONLY));
    l.test(30);

Next: 1.6 Using Classes to Up: 1.5 Basic Program Design Previous: 1.5.4.1 Overriding equals