There are four types or flavors of nested classes in Java. Each type serves different purposes and has unique characteristics:
Static nested class: A static nested class is a static class defined at the member level. It can access all static data members of the outer class and can be accessed without having an instance of the outer class.
Inner class: An inner class is associated with an instance of its enclosing class and can access both static and non-static data members and methods of the outer class. The inner class is instantiated within the context of an object of the outer class.
Local inner class: This class is defined within a block, usually a method block. Local inner classes can access local variables and parameters of the enclosing block that are declared final or effectively final. They are not accessible from outside the block where they are defined, making them very useful for handling event-driven programming or other encapsulated scenarios.
Anonymous inner class: This is a special form of a local inner class that does not have a name. Anonymous inner classes are useful when
making an instance of an object while overloading methods of a class or interface, without having to actually subclass a class.
They are typically used in graphical user interface (GUI) programming for event handling, among other scenarios.
Each of these nested class types is useful in different programming contexts depending on the needs for encapsulation, scope, and access to the enclosing class's members.
The distinctions among these four flavors are not evident at first sight, and it does not help matters that alternative terms are often substituted for them. To help clarify the confusion, we represent the four flavors of nested classes schematically in Figure 3-6:
A non-local class is defined inside a class.(Regular Inner Class)
A Method-local Inner Class is defined within a code block (either a 1) method, 2) constructor, or 3) initialization block)
An anonymous Inner Class, does not provide the name of the class; you just define its body.
A static class is qualified using the static keyword, whereas a non-static class does not use the static keyword with the class definition.
One structure that you can create using static nested classes is to have a static subclass extend a static parent class.
The following link Static Inheritance
gives an example of how this is accomplished.
Static Inheritance using static Nested Classes
You can define a class as a static member inside another class.
The following example demonstrates how a static subclass can extend a parent class that is also declared as static, provided both are contained within a regular class.
In this case 1) Sub and 2) Super are static nested classes of the RegularClass.
static class Sub extends Super and compiles.
package com.java.nestedclasses;
public class RegularClass {
static class Super {
void myMethod() throws Exception {
throw new Exception("throw exception within static parent..");
}
}
static class Sub extends Super {
void myMethod() {
System.out.println("My method");
}
}
public static void main(String[] args) {
new Sub().myMethod();
}
}
/*
Program Output
My method
*/
Member Class Declarations
Member class declarations describe nested classes that are members of the surrounding class.
Member classes may be static, in which case they have no access to the instance variables of the surrounding class;
or they may be inner classes .
Method declarations describe code that may be invoked by method invocation expressions.
A class method is invoked relative to the class type; an instance method is invoked with respect to some particular object that is an instance of a class type.
A method whose declaration does not indicate how it is implemented must be declared abstract.
A method may be declared final, in which case it cannot be hidden or overridden.
A method may be implemented by platform-dependent native code.
A synchronized method automatically locks an object before executing its body and automatically unlocks the object on return,
as if by use of a synchronized statement , thus allowing its activities to be synchronized with those of other threads.
To get you started, here is a question dealing with inner classes and interfaces.
Which of the following options can be a part of a correct inner class declaration
or a combined declaration and instance initialization ?
(Assume that SimpleInterface and ComplexInterface are interfaces.)
Select 2 options:
private class C { }
new SimpleInterface() { //valid code}
new ComplexInterface(x) { //valid code}
private final abstract class C { }
new ComplexClass() implements SimpleInterface { }
Answer: a, b Explanation:
c. You cannot pass parameters when you implement an interface by an anonymous class.
d. A final class can never be abstract.
e. The implements keyword is used only in a class definition and not during instantiation.