Java Inner Classes
Classes defined inside other classes
🏠 What are Inner Classes?
Inner classes are classes defined inside another class. They can access outer class members and provide better encapsulation by grouping related functionality together.
class OuterClass {
private String message = "Hello from Outer";
class InnerClass {
public void display() {
System.out.println(message); // Access outer class member
}
}
}
Output:
Inner class can access outer class members
Types of Inner Classes
Member Inner Class
Regular inner class inside outer class
class Outer {
class Inner { }
}
Static Inner Class
Inner class that doesn't need outer instance
class Outer {
static class StaticInner { }
}
Local Inner Class
Class defined inside a method
void method() {
class LocalInner { }
}
Anonymous Class
Class without a name, defined inline
new Interface() {
// Implementation
};
🔹 Member Inner Class
A regular inner class that has access to all outer class members:
class Computer {
private String brand = "Dell";
private boolean isOn = false;
public void turnOn() {
isOn = true;
System.out.println(brand + " computer is now ON");
}
// Member inner class
class Processor {
private String type = "Intel i7";
public void process() {
if(isOn) { // Access outer class variable
System.out.println(type + " processor is processing on " + brand);
} else {
System.out.println("Computer is OFF. Turn it on first!");
}
}
public void showComputerInfo() {
System.out.println("Computer brand: " + brand); // Direct access
turnOn(); // Call outer class method
}
}
public void createProcessor() {
Processor processor = new Processor();
processor.process();
}
}
// Usage
public class Main {
public static void main(String[] args) {
Computer computer = new Computer();
// Create inner class instance
Computer.Processor processor = computer.new Processor();
processor.process();
processor.showComputerInfo();
processor.process();
}
}
Output:
Computer is OFF. Turn it on first!
Computer brand: Dell
Dell computer is now ON
Intel i7 processor is processing on Dell
🔹 Static Inner Class
Static inner classes don't need an outer class instance:
class University {
private String name = "MIT";
private static String country = "USA";
// Static inner class
static class Department {
private String deptName;
public Department(String deptName) {
this.deptName = deptName;
}
public void showInfo() {
// Can access static outer class members
System.out.println("Department: " + deptName);
System.out.println("Country: " + country);
// Cannot access non-static outer class members
// System.out.println(name); // This would cause error
}
public static void showCountry() {
System.out.println("All universities in: " + country);
}
}
}
// Usage
public class Main {
public static void main(String[] args) {
// Create static inner class without outer instance
University.Department dept = new University.Department("Computer Science");
dept.showInfo();
// Call static method
University.Department.showCountry();
}
}
Output:
Department: Computer Science
Country: USA
All universities in: USA
🔹 Local Inner Class
Classes defined inside methods or blocks:
class Calculator {
public void performOperation(String operation, int a, int b) {
// Local inner class
class Operation {
public void calculate() {
switch(operation.toLowerCase()) {
case "add":
System.out.println(a + " + " + b + " = " + (a + b));
break;
case "multiply":
System.out.println(a + " × " + b + " = " + (a * b));
break;
default:
System.out.println("Unknown operation");
}
}
}
// Use local inner class
Operation op = new Operation();
op.calculate();
}
}
// Usage
Calculator calc = new Calculator();
calc.performOperation("add", 5, 3);
calc.performOperation("multiply", 4, 7);
Output:
5 + 3 = 8
4 × 7 = 28
🔹 Anonymous Inner Class
Classes without names, often used for interfaces or abstract classes:
// Interface
interface Greeting {
void sayHello(String name);
}
public class AnonymousExample {
public static void main(String[] args) {
// Anonymous inner class implementing interface
Greeting greeting = new Greeting() {
@Override
public void sayHello(String name) {
System.out.println("Hello, " + name + "! Nice to meet you.");
}
};
greeting.sayHello("Alice");
// Another anonymous class with different implementation
Greeting formalGreeting = new Greeting() {
@Override
public void sayHello(String name) {
System.out.println("Good day, Mr./Ms. " + name + ".");
}
};
formalGreeting.sayHello("Smith");
}
}
Output:
Hello, Alice! Nice to meet you.
Good day, Mr./Ms. Smith.
🔹 When to Use Inner Classes
- Logical grouping: When a class is only used by one other class
- Encapsulation: To hide implementation details
- Access to private members: When you need access to outer class privates
- Event handling: Common in GUI applications
- Callbacks: Anonymous classes for one-time implementations