The Java TM Tutorial

| Start of Tutorial > Start of Trail > Start of Lesson | Search

Trail: Learning the Java Language
Lesson: 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 (currentItem >= 0);
> >             }
> >             public Object nextElement() {
> >                 if (!hasMoreElements())
> >                     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 (currentItem >= 0);
> >                 }
> >                 public Object nextElement() {
> >                     if (!hasMoreElements())
> >                         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).

| Start of Tutorial > Start of Trail > Start of Lesson | Search