Inner Classes in Java
An inner class is defined within the body of another class. Java provides four distinct types of inner classes: member inner classes, static inner classes, local inner classes, and anonmyous inner classes.
Member Inner Class
A member inner class behaves as a regular class member, allowing declaration of fields and methods. This type of inner class has full access to all members of the outer class, including private members.
public class Vehicle {
private String model;
private int capacity;
public class Engine {
private String fuelType;
private int horsepower;
public void displayPower() {
System.out.println("Horsepower: " + horsepower);
System.out.println("Vehicle model: " + model);
}
}
}
Instantiation requires an outer class instance first:
Vehicle.Engine engine = new Vehicle().new Engine();
engine.displayPower();
When the outer class and inner class define fields with identical names, resolve conflicts using the following approach:
this.year; // refers to inner class field
Vehicle.this.year; // refers to outer class field
Static Inner Class
A static inner class is declared with the static modifier and belongs to the outer class rather than an instance. Unlike member inner classes, a static inner class can only access static members of the outer class.
public class Company {
private static String companyName = "TechCorp";
public static class Department {
private String departmentName;
public void showInfo() {
System.out.println(companyName);
}
}
}
Instantiation differs from member inner classes:
Company.Department dept = new Company.Department();
Local Inner Class
A local inner class is defined within a method, constructor, or initialization block. It exists only within the scope where its defined.
public class Calculator {
public void calculate(int value) {
class MathHelper {
private int result;
public int compute(int input) {
return input * 2;
}
}
MathHelper helper = new MathHelper();
System.out.println(helper.compute(value));
}
}
Anonymous Inner Class
An anonymous inner class is a special form of local inner class without a name. It must extend an existing class or implement an interface. Anonymous inner classes are particularly useful when creating one-off objects for event handlers or callbacks.
Syntax pattern:
new SuperClassOrInterface() {
// implementations
}
Practical example:
public class Handler {
public void process(Runnable task) {
task.run();
}
public static void main(String[] args) {
Handler handler = new Handler();
handler.process(new Runnable() {
@Override
public void run() {
System.out.println("Task executed");
}
});
}
}
Another common use case with abstract classes:
abstract class Shape {
public abstract void draw();
}
public class Canvas {
public void render() {
Shape circle = new Shape() {
@Override
public void draw() {
System.out.println("Drawing circle");
}
};
circle.draw();
}
}