Previous | Next | Trail Map | Learning the Java Language | More Features of the Java Language

Inner Classes

To help you get a handle on inner classes and what they are good for, let's revisit the Stack class. Suppose you want to add a feature to this class that lets another class enumerate over the elements in the stack using the interface defined in java.util.Enumeration. This interface contains two method declarations:
public boolean hasMoreElements();
public Object nextElement();
The Enumeration interface defines the interface for a single loop over the elements:
while (hasMoreElements())
    nextElement()
If Stack implemented the Enumeration interface itself, you could not restart the loop and you could not enumerate the contents more than once. Also, you couldn't allow two enumerations to happen simultaneously. So Stack shouldn't implement Enumeration. Rather, a helper class should do the work for Stack.

The helper class must have access to the Stack's elements. It also must be able to access them directly because the Stack's public interface supports only LIFO access. This is where inner classes come in.

Here's an implementation of Stack that defines a helper class (called an adapter class) for enumerating over its elements:

public class Stack
{
    private Vector items;

    // code for Stack's methods and constructors not shown

    public Enumeration enumerator() {
        return new StackEnum();
    }
    class StackEnum implements Enumeration {
        int currentItem = items.size() - 1;
        public boolean hasMoreElements() {
            return !(isEmpty());
        }
        public Object nextElement() {
            if (isEmpty())
                throw new NoSuchElementException();
            else
                return items.elementAt[currentItem--];
        }
    }
}
Note that the StackEnum class refers directly to Stack's items instance variable.

Inner classes are used primarily to implement adapter classes like the one shown in this example. If you plan on handling events from the AWT, then you'll want to know about using adapter classes because the event-handling mechanism in the AWT makes extensive use of them.

Anonymous Classes

As shown in Using an Inner Class to Implement an Adapter, you can declare a class without a name. Here's yet another version of the now-tired Stack class, in this case using an anonymous class for its enumerator:
public class Stack
{
    private Vector items;

    // code for Stack's methods and constructors not shown

    public Enumeration enumerator() {
        return new Enumeration () {
            int currentItem = items.size() - 1;
            public boolean hasMoreElements() {
                return !(isEmpty());
            }
            public Object nextElement() {
                if (isEmpty())
                    throw new NoSuchElementException();
                else
                    return items.elementAt[currentItem--];
            }
        }
    }
}
Anonymous classes can make code difficult to read. You should limit their use to those classes that are very small (no more than a method or two) and whose use is well-understood (like the AWT event-handling adapter classes).


Previous | Next | Trail Map | Learning the Java Language | More Features of the Java Language