Java Nested Class
Download
Report
Transcript Java Nested Class
Java Programming
Java Nested Class
Cheng-Chia Chen
Transparency No. 1-1
Java Programming
Nested Classes
In addition to a class containing data and methods,
it can also contain other classes
A class declared within another class is called a
nested class (or called inner class)
Outer Class
Nested
Class
Transparency No. 1-2
Java Programming
Why Nested Classes
A nested class has access to the variables and
methods of the outer class, even if they are declared
private
Nested classes can be hidden from other classes in
the same package.
Anonymous classes are handy when defining
callbacks on the fly.
Convenient when writing event-driven programming
Transparency No. 1-3
Java Programming
Nested Classes
A nested class produces a separate bytecode file
If a nested class called Inside is declared in an outer
class called Outside, two bytecode files will be
produced:
Outside.class
Outside$Inside.class
Nested classes can be declared as static, in which
case they cannot refer to this, instance variables or
methods of outer classes.
A nonstatic nested class is called an inner class
Transparency No. 1-4
Java Programming
Kinds of Java classes /interfaces
Top-level classes /interfaces
Non-nested top-level classes/interfaces
are ordinary classes/interfaces that are direct members of a package.
Nested top-level classes / interfaces
are static members of other top-level classes/interfaces
nested interfaces are implicitly static (hence top-level).
Inner classes:
Member classes
are non-static nested classes
Local classes
are classes defined inside method body
Anonymous classes
are classes defined within method body without given a class name
Transparency No. 1-5
Java Programming
Example
class A { …
static A1 { // I am a nested top-level class
…}
A2 { // w/o static modifier, so I am a member class
…}
void m1(…) {
class A3 { // A3 is declared inside a method, so is a
local class …}
…}
void m2(…) { // A4 is an interface or class
A4 a = new A4() { void m3() {…} m4() … };
// a is an object of an anonymous
subclass/implementation of A4.
Transparency No. 1-6
Java Programming
Nested top-level classes /interfaces
also called static member classes/interfaces
behave like an ordinary top-level class/interface
except that
it can access the static members of all of its direct or
indirect containing classes (even they are private).
can be public, protected, package or private.
Access rules for fields&methods applicable to nested classes also.
Should use the name A.B.C for a reference to class C
enclosed by class B enclosed by class A.
A
B
A
B
C
Transparency No. 1-7
Java Programming
Example of a static member interface
public class LinkedStack { // stack of Linkable objects
public interface Linkable { // interfaces are static by default.
public Linkable getNext();
top
Linkable
getNext()
public void setNext(Linkable node); }
Linkable
Linkable
Linkable
Linkable top; // top of stack
LinkedStack
public LinkedStack() {};
Linkable
null
pubic boolean empty() { return (top == null) ;}
public void push(Linkable node) { node.setNext(top); top = node; }
public Object pop(Linkable node) throw EmptyStackException {
if(empty()) throw new EmptyStackException();
Object r = top; top = top.getNext(); return r; } }
Transparency No. 1-8
Java Programming
// This class defines a type of node that we'd like to
// use in a linkedStack.
class IntegerNode implements LinkedStack.Linkable
{
// Here's the node's data and constructor.
public int i;
public IntegerNode(int i) { this.i = i; }
// implementation of LinkedStack.Linkable.
private LinkedList.Linkable next;
public LinkedList.Linkable getNext() { return next; }
public void setNext(LinkedList.Linkable node)
{ next = node; }
}
Transparency No. 1-9
Java Programming
public class test {
pubic static void main(String[] args) {
// declare an array of 10 IntergerNodes
IntergerNode[] n = new IntergerNode[10];
LinkedStack s = null;
for (int i = 0; i < n.length; i++) {
n[i] = new IntergerNode(i);
s.push(n[i]) ;
}
while(! s.empty()) System.out.println(s.pop());
}
Transparency No. 1-10
Java Programming
Features of static nested classes
obey the same rules of static methods:
1. can access only static members (using simple or full
name) but no matter they are private or not.
2. accessible to other classes according to the used
visibility modifier.
Note: useful for compiler only.
2
static Nested
as to JVM :
class
pubic or protected nested/member classes
1
=> visible to all classes,
2
package or private nested/member classes
Outer class
=> visible to containing package
Transparency No. 1-11
Java Programming
How is a nested class referenced ?
How to reference a nested static class C inside
[static] class A of [static] class B of package a.b :
1. outside package a.b => a.b.A.B.C
if import a.b.A.B.C or a.b.A.B.* => C // not recommended
if import a.b.A.B or a.b.A.* => B.C // not recommended
2. inside package a.b => A.B.C (or a.b.A.B.C)
3. inside class A => B.C (or A.B.C or a.b.A.B.C)
4. inside class B => C ( or any of the above)
1. a.b.A.B.C
a.b
3. B.C
A
2. A.B.C
B
A
B
C
4.C
Transparency No. 1-12
Java Programming
Example
import LinkedStack.Linkable;
// or import LinkedStack.*;
class IntegerNode implements Linkable
{
// Here's the node's data and constructor.
private int i;
public IntegerNode(int i) { this.i = i; }
// implementation of LinkedStack.Linkable.
private LinkedList.Linkable next;
public Linkable getNext() { return next; }
public void setNext(Linkable node)
{ next = node; }
}
Transparency No. 1-13
Java Programming
Access rules among nested/containing and nested/nested classes
motivation:
Since all java code inside a java class can access all
members of the same class, it is rational to allow nested
class to access all (even private) members of its outer
classes as well.
All static fields, methods, and classes of a top level
class are accessible to all code [even inside a static
class] within the class no matter they are private or
not.
Transparency No. 1-14
Java Programming
access references in nested classes
public class A { static int a; static private int ma();
static class B1 { static int b1; static private int mb1();
static class C1 { static int c1; static int mc1(); }}
static class B2 {
static class B1 { … }
static int b2; static private int mb2();
static class C2 { // various ways to access other members
// a, A.a, ma(), A.ma(), B1, A.B1 reference A’s members
// b2, B2.b2, A.B2.b2, mb2, B2.mb2(), A.B2.mb2(), B2.B1, B1.
// A.B1.b1, A.B1.C1.c1, B1.C1.c1, C1.c1
}}}
Transparency No. 1-15
Java Programming
A
A.a
-int a ;
-int ma();
#B1
a
ma()
A.B1.b1
#int b1 ;
#int mb1();
A.B1.C1.c1
C1
int c1 ;
int mc1();
B1
B1.b1
+B2
- int b2 ;
- int ma();
B1
B1.C1.c1
B2.b2
B1.b11
b2, ma()
C2
int b11 ;
int mb11();
viewed
from here!!
Transparency No. 1-16
Java Programming
Tree view of nested classes
A
A.ma()
a
ma()
A.B2.b2
B2
B1
B2
a, ma()
A.B1.b1
B1
b1
mb1()
b2
ma()
B1
B1.b1
B1
A.B1.C1.c1
C1
C1
c1
mc1()
A.B2.B1.b11
b2,ma()
B1
b11
mb11()
C2
B1.C1..c1
mc2() { }
B1.b11
viewed from here!!
Transparency No. 1-17
Java Programming
Member classes
static class behaves like static fields/methods
member class behaves like instance fields/methods
beside referring to all static fields/methods, can also reference this,
instance field/method of all enclosing classes, even they are private.
associated with an instance of each of the enclosing classes
Member class v.s. Static class
static class and its enclosing classes are static class-class relationship
member class and its enclosing classes are instance-instance
relationship.
1. Each member class instance must be created/accessed through
instances of the containing class.
2. Each member class instance is associated with an unique instance
of its containing class.
Transparency No. 1-18
Java Programming
Example: A LinkedList Iterator, as a Member Class
import java.util.Iterator;
public class LinkedStack { // those from old LinkedStack
public interface Linkable { ... }
private Linkable top;
public void push(…) { ... } public Object pop() { ... }
// This method returns an Iterator object for this LinkedStack.
// Note: no LinkedStack object is explicitly passed to the
//
constructor.
public Iterator iterate() { return new MyIterator(); }
Transparency No. 1-19
Java Programming
Example: A LinkedList Iterator, as a Member Class
// the implementation of the Iterator interface.
Linkable
protected class MyIterator implements Iterator {
Linkable current ;
MyIterator
public MyIterator() { current = top; }
LinkedStack
public boolean hasNext() { return (current != null); }
public Object next() {
if (current == null) throw new NoSuchElementException("LinkedStack");
Object rlt = current; current = current.getNext();
return rlt; }
public remove() { throw new UnsupportedOperationException() ; }
}}
Note: MyIterator is is part of LinkedStack class and is
accessible only to subclasses or the package of LinkedStack.
Transparency No. 1-20
Java Programming
Restrictions on member classes
Outer package/class and inner class cannot have the same
name.
Ancestors and descendants cannot have the same name.( A{ B { A }})
siblings cannot have the same name.( A{ B{} B{} } )
siblings and nephews can have the same name. (A { B{} C{ B {}} } )
Member classes cannot contain any static fields, methods or
classes (with the exception of constant fields).
since member class is associated with object instances, it is
nonsense/needless to have static members.
… static static ... , … static non-static …, non-static non-static … (ok!)
… non-static static … (X)
Interfaces cannot be defined as member classes.
since interfaces cannot be instantiated, there is no way for an object
to create an interface instance.
A nested interface is by default static, even if the modifier ‘static’ is
not given in the header.
Transparency No. 1-21
Java Programming
New syntax for member classes
member class can access instance field/method of containing
class.
A : int f
public MyIterator() { current = top; }
B:int f
How to make the reference explicit if there are
more than one containing classes ?
public MyIterator() { this.current = this.top;}
// this.current ok ; but this.top err!!
// since there is no top in the nearest class MyIterator
C :{ int f
f, this.f // ?
B.this.f, A.this.f
}
Solution: // allow multiple “this” by quantify it with class name.
public MyIterator() { this.current = LinkedStack.this.top;}
New syntax: C: a containing class name
C.this is used to reference the associated C instance.
C.this style needed only when omitting it incurs ambiguity.
Transparency No. 1-22
Java Programming
accessing superclass members of the containing class
Recall that we use super.f (or super.m(…)) to reference
shadowed or overridden member of parent class of this.
Likewise, we use
C.super.f
to reference the f field of the parent class of C, which is a
containing class of this, and use
C.super.m()
to reference the method m() of the parent class of C.
Transparency No. 1-23
Java Programming
SA
a, f :int
A
A.this.f a
A.this.a
ma()
a
invisible
A.super.a ((SA) A.this).a
B
SuperB
B1
B
B1
B.this
b1
mb1()
C1
C1
c1
mc1()
B.super.m()
b2
ma()
B1
visible!
invisible
unless B1
is static
SuperC
B1
b11
mb11()
C
this
super.m()
mc() { }
viewed from here!!
Transparency No. 1-24
using containing class instance to invoke constructors
of member class
Java Programming
Every instance of a member class is associated with
an instance of its containing class.
pubic Iterator iterate(){return new MyIterator();}
can also be written as
pubic Iterator iterate() { return this.new MyIterator() ;}
More useful case:
LinkedStack stack = new LinkedStack();
Iterator e1 = stack.iterate();
// could create one instance of MyIterator directly!!
Iterator e2 = stack.new MyIterator();
syntax: C: a containing class of member class D
with constructor D(…); s : this or var of type C
s.new D(…) will invoke D(…) of class D in an instance of C
referenced by s.
Transparency No. 1-25
Java Programming
Some special case
It is possible that a class extends a member class.
public class A { … public class B { …} …}
class C extend A.B {
pubic C( … ) { ??? } … }
problem: what is the instance of A that would
contain the B instance which is the parent of C?
Solution:
Require the users pass as the first parameter the needed
A instance.
pubic C( A a, … ) {
a.super(…); // like call A.new B(…) here!
… }
Transparency No. 1-26
Java Programming
Containing Hierarchy vs Inheritance Hierarchy
class A extends A1 { int x;
class B extends B1 { int x;
class C extends C1 { int x; …} } }
class A1 { int x; …}
class B1 { int x; …}
class C1 extends C2 { int x; …}
class C2 { int x; … }
Problem: how to reference different x in class C.
this.x, C.this.x // x in C B.this.x // x in B
A.this.x // x in A
super.x, ((C1)this).x // x in C1
((C2)this).x // x in C2
((B1) (B.this)).x, B.super.x // x in B1
((A1) (A.this)).x, A.super.x // x in A1
Problem: how about overridden methods ?
Transparency No. 1-27
Java Programming
A.super
A
A.this
A1
x
m()
x
m()
B.super.x,
((B1)B.this).x
B.super.m()
B1
C2
x
m()
x
m()
B
B.this.x
B.this.m()
x
C1
m()
C
x, this.x, C.this.x
m(), this.m,C.this.m()
((C2) this)).x
m() is not accessible!!
x
m()
super.x, ((C1) this)).x
x
super.m()
m()
m2(){} viewed from here!!
Transparency No. 1-28
Java Programming
Local Classes
class declared locally within a block of Java code.
within method body
within instance/static initialization block
Feature of Local class:
Local class is to member class what local variable is to
instance variable.
Properties similar to local variables:
1. invisible outside the containing block.
2. cannot use accessibility or static modifiers
Properties similar to member classes
1.can access any member of any containing classes.
2. no local interfaces
can use any final local variables/method parameters that
are visible from the scope in which they are defined.
Transparency No. 1-29
Java Programming
Example: Defining and using a Local Class
// This method creates and returns an Iterator object for this LinkedStack.
public Iterator iterate() {
// Here's the definition of Enumerator as a local class.
class MyIterator implements Iterator {
Linkable current;
public MyIterator() { current = top; }
public boolean hasNext() { return (current != null); }
public Object next() { … } // omitted
public remove() {… } // omitted
}
// Create and return an instance of the Enumerator class defined here.
return new MyIterator();
}
Transparency No. 1-30
Java Programming
Fields and variables accessible to a local class
class A { protected char a = 'a'; }
class B { protected char b = 'b'; }
pubic class C extends A {
public static void main(String[] args) {
// Create an instance of the containing class, and invoke the
// method that defines and creates the local class.
C c = new C();
c.createLocalObject('e'); // pass a value for final parameter e.
}
Transparency No. 1-31
Java Programming
private char c = 'c';
// Private fields visible to local class.
public static char d = 'd';
public void createLocalObject(final char e) {
final char f = 'f'; int i = 0; // i not final; not usable by local class.
class Local extends B { char g = 'g';
public void printVars() { // All of these fields and variables are accessible.
out.println(g); // (this.g) g is a field of this class.
out.println(f); // f is a final local variable.
out.println(e); // e is a final local argument.
out.println(d); // (C.this.d) d -- field of containing class.
out.println(c); // (C.this.c) c -- field of containing class.
out.println(b); // b is inherited by this class.
out.println(a); // a is inherited by the containing class.
} } // end of Local
Local l = this.new Local(); // Create an instance of the local class
l.printVars();
// and call its printVars() method. }
Transparency No. 1-32
Java Programming
Anonymous classes
a local class without a name
very commonly used as adapter classes.
created through another extension to the syntax of
the new operator.
defined as a Java expression, not as a Java
statement.
Transparency No. 1-33
Java Programming
Example: Implementing an Interface with an Anonymous Class
import java.io.*;
// A simple program to list all Java source files in a directory
public class Lister {
public static void main(String[] args) {
File dir = new File(args[0]); // f represents the specified directory.
// List the files in the directory, using the specified filter object.
// The anonymous class is defined as part of a method call expression.
String[] list = dir.list( new FilenameFilter() {
public boolean accept(File f, String name) {
return name.endsWith(".java");
}});
for(int i = 0; i < list.length; i++) // output the list
System.out.println(list[i]);
}}
Transparency No. 1-34
Java Programming
Anonymous class vs local class
when to use anonymous class:
The class has a very short body.
Only one instance of the class is needed.
The class is used right after it is defined.
The name of the class does not make your code any easier
to understand.
Restrictions on anonymous classes:
An anonymous class has no name and hence cannot be
used to create more than one instance for each execution.
It is not possible/needed to define constructors for
anonymous classes.
Transparency No. 1-35
Example: iterate implemented as an anonymous class
Java Programming
public Iterator iterate() {
// Instantiate and return this implementation.
return new Iterator() {
Linkable current = top; // This used to be in the constructor, but
// anonymous classes don't have constructors.
public boolean hasNext() { return (current != null); }
public Object next() {
if (current == null) throw new NoSuchElementException("LinkedList");
Object value = current;
current = current.getNext();
return value; }
public void remove() {… } // omitted!
}; // Note the required semicolon. It terminates the return statement.
}
Transparency No. 1-36
Java Programming
Additional Java Syntax for Anonymous Classes
syntax:
new class-name ( [ argument-list ] ) { class-body }
new interface-name () { class-body }
Syntax 1 return an instance of an anonymous subclass of classname
argument-list is the actual argument list matching one constructor of
the abstract class.
the subclass can provide additional (helper ) methods/fields and/or
overrides or implements existing super class methods.
Ex: Object o = new Object() { Date date = new Date() ; void print() {…} }
Syntax 2 return an instance of a class implementing interfacename.
Transparency No. 1-37
Java Programming
use initializer to help construct [anonymous] class instances
public class InitializerDemo { public int[] array1;
// This is an instance initializer.
// It runs for every new instance, after the superclass constructor
// and before the class constructor, if any.
{ array1 = new int[10];
for(int i = 0; i < 10; i++) array1[i] = i; }
// another instance initializer. The instance initializers run in the order in
// which they appear.
int[] array2 = new int[10]; { for(int i=0; i<10; i++) array2[i] = i*2; }
static int[] static_array = new int[10];
// By contrast, the block below is a static initializer. Note the static
// keyword. It runs only once, when the class is first loaded.
static {
for(int i = 0; i < 10; i++) static_array[i] = i; }
}
Transparency No. 1-38
Java Programming
Some other notes
Class Literals:
Each user or system defined class is represented by an
object of the type java.lang.Class at runtime.
Given a fully qualified class name a.b.C, there are two
ways to refer to the Class object representing a.b.C:
1. Class.forName(“a.b.C”)
2. a.b.C.class
a.b.C.D.class
(2.) is useful for inner classes as well; as to (1.) it requires
special knowledge of how inner classes is translated into
top level classes.
Class.forName(a.b.C$D); // a.b.C.D.class
Transparency No. 1-39
Java Programming
Default value of variables
Kinds of variables:
1.
2.
3.
4.
5.
6.
7.
class/static variables
instance variables
local variables
formal method parameters
formal constructor parameters
array component : int[ ] ar = new int[10] ; // => ar[0] .. ar[9]
exception-handler parameters
Notes about default value of uninitalized variables:
1. Default values are given only to array components or
class/instance variables which are not final.
2. Local variables are not assigned default values.
Transparency No. 1-40
Java Programming
Blank Final
Blank finals
a field or local variable declared final but without given an
initial value in the declaration.
Recall that a final variable cannot be reassigned values
(for primitive type) or references (for array or object type)
once it has been given a content.
public class Test
{ final int y = 10 ; // y is final but not blank final.
int z ; // z is not final and has default value 0
final int x ; // x is blank final, has no value here
{ x = 1; } // x assigned value for the 1st time. ok!
Transparency No. 1-41
Java Programming
Blank final
public void setX(int nx, final int ny) {
x = nx; //error, final field x reassigned value.
// still error even removing {x=1;} why ?
// no way to determine if x = nx will be executed once only.
nx = nx + 10 ; // ok, nx is not final and has value
ny = ny + 10 ; // error, final ny reassigned value
final int nx10 = nx; // ok
final int nx11 ; // blank final
int nz
// local var has no default value
nx = nz + 1;
// error nz has no value here
nz = nx11 = nx; // ok
nx11 = nx; // error }}
Transparency No. 1-42
Java Programming
Object of final variable can change state.
class Man extends Person {
final Women wife = findAWife(..);
final Person[] children = new Person[5] ;
…
public void m() {
wife.name = newName(); // ok, final object changes state
wife = FindAnotherWife(…) // error! final var changes
reference
children[0] = bearOne(…); // ok! final object can change
state
children = FindChilren(..) // error!
}
Transparency No. 1-43
Java Programming
References
References:
Java Inner Class Specification
Nested Classes (From Java Tutorials)
Inner Classes and Enclosing Instances (From
JavaLangSpec 3rd edition)
Transparency No. 1-44