🪆
OOP

Nested & Inner Classes

Class Inside a Class
💡 A nested class is like a matryoshka (Russian doll) — a class hidden inside another class, working closely with the outer one.

A static nested class can be used independently, without an outer class object — accessed just as Outer.Nested.

A non-static Inner class is tied to an outer object — it can directly see the outer's instance members too.

An anonymous class is a nameless class defined for immediate, one-time use — like a button click listener.

class Outer {
  static class Nested { void show() { System.out.println("Nested"); } }
  class Inner { void show() { System.out.println("Inner"); } }
}
🪆
A nested class is like a matryoshka (Russian doll) — a class hidden inside another class, working closely with the outer one.
1 / 4
⚡ Quick Recap
  • Static nested = an independent helper class
  • Inner = tied to an outer object
  • Anonymous = nameless, one-time use
On this page (4 subtopics)

A static nested class can be built without an object of the outer class — Outer.Nested obj = new Outer.Nested(). This is used when a helper class needs no connection to the outer instance, and is just kept inside for naming/grouping (like Map.Entry, a static nested interface inside the Map interface).

class Outer {
  static class Nested {
    void show() { System.out.println("Static nested!"); }
  }
}
Outer.Nested n = new Outer.Nested(); // outer object nahi chahiye

To build a non-static inner class, you first need an object of the outer class (outerObj.new Inner()). The benefit: the inner class can directly access all the outer's instance fields/methods, without explicitly passing them — because an inner class implicitly holds a reference to the outer object.

class Outer {
  int x = 10;
  class Inner {
    void show() { System.out.println(x); } // outer ka x directly
  }
}
Outer o = new Outer();
Outer.Inner i = o.new Inner(); // outer object zaroori hai

You can define a class right inside a method — a "local class". It's usable only within that method, and can capture the method's local (effectively final) variables. It's a rare use-case, but sometimes useful when a complex helper logic needs to be scoped inside just one method.

A nameless class that's defined and instantiated immediately, for one-time use — in older Java, event listeners were written exactly this way (before Java 8's lambdas). Still useful today when you need a one-time-use implementation of an interface/abstract class, and that interface isn't functional (single-method) — where a lambda wouldn't work.

Runnable r = new Runnable() {
  public void run() { System.out.println("Running!"); }
};