
CS102: Inner Classes and Adapters
Copyright © 1999, Kenneth
J. Goldman
-
Inner Classes
Sometimes we define a class whose purpose is only to "help out" another
class.
For example, the ListItem class for a LinkedList class. In that kind
of situation,
it would be nice if the helper class didn't stand on its own, but instead
was more closely
assoiciated with the class itself.
So far, all classes we have defined have been "top level classes."
In other words,
as far as the Java compiler is concerned, the classes are independant
and
exist on there own.
We have done some things in CS101 and CS102 to capture the sense that
two classes
belong together. Namely, we have
Put the classes in the same file (only one is public)
Put the class in the same package
These are helpful, but neither really says that one class is somehow "part
of" another class.
To express this kind of relationship between classes, Java programmers
can use something
called "inner classes."
There are four varieties of inner classes. We'll take a look at each
one and give some examples.
-
A Nested top-level class (or interface)
-
A Member class
-
A Local class
-
An Anonymous class
Nested Top Level Classes
This is a class defined as a static class member. Its still
really a top-level class, but from outside
its name is prefixed with the name of the containing class seperated
by a dot. Access to the class
can be controlled through protection modifiers.
For example:
public class Animation
extends Component{
public Animation(....){
....
addMouseListener( new
AnimationRequestHandler() );
....
}
public void beginAnimation(){
//Note 1
....
}
private static class
AnimationRequestHandler extends MouseAdapter{
public void mouseClicked(MouseEvent
e){
((Animation)(e.getSource()))).beginAnimation();
//Note 2
}
}
}
Note 1: beginAnimation() must be public becauce AnimationRequestHandler
is a top level class
and has no special access to methods in Animation, i.e. the innner
class AnimationRequestHandler
can access only public methods and public instance variables of the
Animation class, not private ones.
Note 2: Just like with any other method, you must use objectName.methodName()
notation for
beginAnimation().
Member Classes
These are not top level classes - they are declared like instance variables
and methods (not static)
and each instance of a member class has a corresponding instance of
the containing class (usually the
one that created it).
Instances of member classes have access to the instance variables and
methods of the containing
class (and vice versa), as well as other member class instance variables
and methods created by the
original class. (Bug: some compilers don't allow access to private
members)
For example:
public class Animation
extends Component{
public Animation(....){
....
addMouseListener( new
AnimationRequestHandler() );
....
}
void beginAnimation(){
//Note 1
....
}
private class AnimationRequestHandler
extends MouseAdapter{
public void mouseClicked(MouseEvent
e){
beginAnimation();
//Note 2
}
}
}
Note 1: beginAnimation() does not need to be public becauce AnimationRequestHandler
is member
class and has access to methods in Animation, i.e. the member
class AnimationRequestHandler
can access any method or instance variable of the Animation
class.
Note 2: This time beginAnimation() can be called without a source because
there is only one object it
could belong to.
Technical Note: Member classes can't contain any static members and
they can't have the same name
as any containing class or package.
Local Classes
These are similar to member classes, except that they are declared
within a method, and have access
to final local variables within that scope and they are only
visible and usable within that scope.
For Example:
public class Animation
extends Component{
public Animation(....){
class AnimationRequestHandler
extends MouseAdapter{
public void mouseClicked(MouseEvent
e){
beginAnimation();
}
}
........
addMouseListener( new
AnimationRequestHandler() );
........
}
void beginAnimation(){
//Note 1
......
}
}
Local classes have the same restrictions as member classes: local classes
can't contain any static
members and they can't have the same name as any containing class or
package.
Anonymous Classes
These are similar to local classes, except they have no names. Instead,
they are defined within the
expression that intantiates them.
Anonymous classes either
extend a class, or
implement an interfance (and extend Object)
It is typical to extend an adapter, as in the following example:
public class Animation
extends Component{
public Animation(....){
....
addMouseListener( new
MouseAdapter(){ //Note
1
public void mouseClicked(MouseEvent
e){
beginAnimation();
}
});
........
}
void beginAnimation(){
......
}
}
Note 1: MouseAdapter is the name of the class being extended or interface
being implemented.
Any parameters to the contstucter for mouseAdapter need to be included.
An anonymous class inherits its contructor because it can't define its
own.
An anonymous class has no name.
An anonymous class has no protection modifiers - it has no name, so
you can't access it from outside anyway.

