A cardinal rule in Scheme programming is ``Never repeat code''. If a program repeats essentially the same code in two or more places, then the programmer failed to identify a common abstraction that should only be written once. The repeated code sections can be replaced by calls on a procedure that defines the repeated operation. Any minor differences between the repeating code sections can be accommodated by passing appropriate arguments that ``fill in'' the differing expressions.
The same rule applies to Java, but the notational details are more cumbersome because (i) methods cannot be directly passed as arguments in Java and and (ii) Java is statically typed. Passing methods as arguments is such an important programming technique that object-oriented programmers have developed a design pattern, called the command pattern, that enables Java programs to indirectly pass methods as parameters by embedding them in ``dummy'' objects called commands. This pattern is discussed in the next subsection. The complicating effects of Java's static type discipline are illustrated by the following example.
Consider a program that manipulates lists of several different types of elements. One approach is to define a separate composite class hierarchy for each kind of list. But this approach requires replicating essentially the same code in the definition of each class. To avoid this code replication, we can define a single composite class hierarchy for lists of type Object. Since all Java object types are subtypes of Object, such a list type can be used in place of any specific list type. However, when we extract an element from such a list, we will generally have to cast it to the specific type required by the context in which it is used. These casting operations clutter the code and reduce the precision of static type checking. Nevertheless, the advantages conferred by avoiding code replication usually outweigh these disadvantages.
Finger Exercise Load the sample IntList1 program into the DrJava Definitions window. Convert it to a definition of a class ObjectList where the list elements have type Object instead of type int. Test this program and save it in a file objectList.java for future use.
Finger Exercise Load the program in your saved file objectList.java into the Definitions window. Define a method
ObjectList sort()that sorts a list of Integer into non-descending order, akin to the sort method on IntList that you defined in section 1.7. Your code will need to use casting operations confirming that the elements in the receiver of a sort invocation have type Integer. Test your code. What happens if you try to sort a list containing elements that are not of type Integer?