Java allows defining a class inside another class, which is called an inner class. Inner classes are categorized into member inner classes, local inner classes, anonymous inner classes, and static inner classes.
1. Member Inner Classes
A member inner class has unrestricted access to all members of the enclosing outer class, even private ones. However, members of the inner class are only visible within the inner class scope and cannot be accessed directly from the outer class.
Instantiation of an inner class object must occur with in the outer class context. To distinguish referances when variable names collide, use this for the inner class instance and OuterClassName.this for the outer class instance.
public class TheSameName{
private int x;
private class Inner{
private int x = 9;
public void doit(int x){
x++; // refers to method parameter x
this.x++; // refers to inner class variable x
TheSameName.this.x++; // refers to outer class variable x
}
}
}
2. Local Inner Classes
A local inner class is defined within a method block. It is part of the method, not a member of the outer class, so it cannot be accessed outside the method. However, it can access the method's final or effectively final parameters, constants, and all members of the outer class.
interface OutInterface2{
}
class OuterClass3{
public OutInterface2 doit(final String x){
class InnerClass2 implements OutInterface2{
InnerClass2(String s){
s = x;
System.out.println(s);
}
}
return new InnerClass2("doit");
}
}
3. Anonymous Inner Classes
An anonymous inner class is declared and instantiated simultaneously. It must implement all methods of an interface or extend a class within the braces. This is typically used to create a one-shot implementation.
return new A(){
// class body
};
The following example creates an anonymous object implementing OutInterface2:
class OuterClass4{
public OutInterface2 doit(){
return new OutInterface2(){
private int i = 0;
public int getValue(){
return i;
}
}; // semicolon ends the expression, not the class definition
}
}
4. Static Inner Classes
Adding the static modifier to an inner class makes it static. A static inner class can contain static members, whereas a non-static inner class cannot. Static inner classes cannot access non-static members of the outer class directly.
5. Inheriting Inner Classes
When inheriting an inner class, the subclass constructor must accept a reference to an instance of the outer class and use outer.super() to properly chain the constructor.
public class OutputInnerClass extends ClassA.ClassB{
public OutputInnerClass(ClassA a){
a.super();
}
}
class ClassA{
class ClassB{
}
}
This ensures the necessary enclosing instance is provided for the inner class inheritance.