An Inner Class (or Nested Class) is a class defined inside another enclosing class or function. They help logically group helper types, improve encapsulation, and restrict helper visibility to where it matters most.
While Java distinguishes sharply between static nested classes (no outer instance reference) and non-static inner classes (holds an implicit outer instance reference), C++ and Python treat nested classes as naturally independent types scoped within the outer class namespace.
There are 4 main categories of inner / nested class patterns:
A static nested class does not require an instance of the enclosing class. It can access outer
static members directly, but cannot access outer instance members without an
explicit object reference.
class OuterClass {
static int staticVar = 100;
// Static Nested Class
static class StaticNestedClass {
void display() {
System.out.println("Static variable: " + staticVar);
}
}
}
public class Main {
public static void main(String[] args) {
OuterClass.StaticNestedClass nestedObj = new OuterClass.StaticNestedClass();
nestedObj.display(); // Output: Static variable: 100
}
}
#include <iostream>
using namespace std;
class OuterClass {
public:
static int staticVar;
// Nested class (naturally independent in C++)
class NestedClass {
public:
void display() {
cout << "Static variable: " << OuterClass::staticVar << "\n";
}
};
};
int OuterClass::staticVar = 100;
int main() {
OuterClass::NestedClass nestedObj;
nestedObj.display(); // Output: Static variable: 100
return 0;
}
class OuterClass:
static_var = 100
# Nested class (independent by default in Python)
class StaticNestedClass:
def display(self):
print("Static variable:", OuterClass.static_var)
def main():
nested_obj = OuterClass.StaticNestedClass()
nested_obj.display() # Output: Static variable: 100
if __name__ == "__main__":
main()
A non-static inner class is associated with an instance of the outer class.
OuterClass.this) to the outer instance.
class OuterClass {
int instanceVar = 42;
// Non-static Inner Class
class InnerClass {
void display() {
// Implicit access to outer instance variable
System.out.println("Instance variable: " + instanceVar);
}
}
}
public class Main {
public static void main(String[] args) {
OuterClass outerObj = new OuterClass();
OuterClass.InnerClass innerObj = outerObj.new InnerClass();
innerObj.display(); // Output: Instance variable: 42
}
}
#include <iostream>
using namespace std;
class OuterClass {
public:
int instanceVar = 42;
// Nested class storing explicit reference to outer instance
class InnerClass {
OuterClass &outer;
public:
InnerClass(OuterClass &outerRef) : outer(outerRef) {}
void display() {
cout << "Instance variable: " << outer.instanceVar << "\n";
}
};
};
int main() {
OuterClass outerObj;
OuterClass::InnerClass innerObj(outerObj);
innerObj.display(); // Output: Instance variable: 42
return 0;
}
class OuterClass:
def __init__(self):
self.instance_var = 42
class InnerClass:
def __init__(self, outer):
self.outer = outer
def display(self):
print("Instance variable:", self.outer.instance_var)
def main():
outer_obj = OuterClass()
inner_obj = OuterClass.InnerClass(outer_obj)
inner_obj.display() # Output: Instance variable: 42
if __name__ == "__main__":
main()
Local inner classes are declared inside a method or function block and are only visible within that method's scope.
class OuterClass {
void outerMethod() {
int localVar = 10; // Effectively final
// Local Inner Class
class LocalInnerClass {
void display() {
System.out.println("Local variable: " + localVar);
}
}
LocalInnerClass localInner = new LocalInnerClass();
localInner.display(); // Output: Local variable: 10
}
}
public class Main {
public static void main(String[] args) {
OuterClass outerObj = new OuterClass();
outerObj.outerMethod();
}
}
#include <iostream>
using namespace std;
class OuterClass {
public:
void outerMethod() {
int localVar = 10;
// Local class inside a method
class LocalInnerClass {
int captured;
public:
LocalInnerClass(int x) : captured(x) {}
void display() {
cout << "Local variable: " << captured << "\n";
}
};
LocalInnerClass localInner(localVar);
localInner.display(); // Output: Local variable: 10
}
};
int main() {
OuterClass outerObj;
outerObj.outerMethod();
return 0;
}
class OuterClass:
def outer_method(self):
local_var = 10
# Local class inside a method
class LocalInnerClass:
def __init__(self, x):
self.captured = x
def display(self):
print("Local variable:", self.captured)
local_inner = LocalInnerClass(local_var)
local_inner.display() # Output: Local variable: 10
def main():
outer_obj = OuterClass()
outer_obj.outer_method()
if __name__ == "__main__":
main()
Anonymous inner classes have no name and are instantiated at the point of declaration for one-time use (e.g., event listeners or single-use interface implementations).
In modern C++ and Python, one-time behavior is almost universally implemented using Lambdas or inline function objects rather than verbose anonymous class structures.
abstract class Greeting {
abstract void sayHello();
}
public class Main {
public static void main(String[] args) {
// Anonymous Inner Class
Greeting greeting = new Greeting() {
void sayHello() {
System.out.println("Hello, World!");
}
};
greeting.sayHello(); // Output: Hello, World!
}
}
#include <iostream>
using namespace std;
int main() {
// Lambda expression (modern C++ anonymous function)
auto sayHello = []() {
cout << "Hello, World!\n";
};
sayHello(); // Output: Hello, World!
return 0;
}
def main():
# Lambda expression (anonymous inline function)
say_hello = lambda: print("Hello, World!")
say_hello() # Output: Hello, World!
if __name__ == "__main__":
main()
| Pattern | Java | C++ | Python |
|---|---|---|---|
| Static Nested | Declared with static; no outer instance reference |
Naturally independent nested class; scoped type | Nested class by default; scoped namespace |
| Non-Static Inner | Implicit outer reference (OuterClass.this) |
Explicit reference/pointer to outer stored in nested class | Explicit outer object reference passed into __init__ |
| Local Class | Captures effectively final local method variables | Defined in function scope; manual constructor capture required | Defined in method scope; manual constructor capture recommended |
| Anonymous / One-time | Anonymous inner class or Lambda expressions | Lambda expressions ([captures](params) { body }) |
Lambda expressions (lambda: expr) or small helper functions |
In Java, how do you instantiate a non-static inner class Inner of
Outer?
Does a nested class in C++ automatically hold a reference to its outer class instance?
Nested Class ⇒ Class defined inside another class or function scope
Goal ⇒ Encapsulation ; logical grouping ; namespace clutter reduction
Java ⇒ static class Inner ; no outer instance binding
C++ / Python ⇒ Naturally independent by default ; access outer static members via
Outer::var or Outer.var
Java ⇒ Holds implicit outer reference (OuterClass.this) ; created via
outerObj.new Inner()
C++ / Python ⇒ No auto-binding ; pass & store outer reference/pointer explicitly in constructor
Local Class ⇒ Defined inside function ; Java captures effectively final vars ; C++/Python require explicit constructor arguments
Anonymous / One-time ⇒ Java uses anonymous inner classes or lambdas ; C++ and Python prefer Lambdas
Primary source: Oracle Java Tutorials — Nested Classes & cppreference — Nested Class Declarations. Ask me anything that's unclear.
Questions? Ask your agent — you can follow up on any concept, quiz answer, or how this applies to a specific coding problem. Review the Java glossary or syntax quick reference for a compressed overview.