In Kotlin, classes can be defined inside other classes to logically group and encapsulate related functionality. These are known as nested and inner classes. Although they look similar, they behave differently in how they access members of the outer class.
Nested and inner classes improve structure and encapsulation:
A nested class is simply a class defined inside another class. By default, it does not hold a reference to the outer class and cannot access its members.
class Outer {
private val outerName = "Outer Class"
class Nested {
fun show() = "Hello from Nested Class"
// Cannot access outerName directly
}
}
fun main() {
val nested = Outer.Nested() // No need to create Outer instance
println(nested.show())
}
Output:
Hello from Nested Class
class Nested inside another class.
If you want the nested class to access the members of the outer class,
you must declare it as an inner class using the inner keyword.
class Outer {
private val outerName = "Outer Class"
inner class Inner {
fun show() = "Accessing: $outerName from Inner Class"
}
}
fun main() {
val inner = Outer().Inner() // Requires Outer instance
println(inner.show())
}
Output:
Accessing: Outer Class from Inner Class
inner keyword.
The this@OuterClassName syntax allows inner classes to explicitly refer to the outer class instance.
class Outer {
private val outerName = "Outer"
inner class Inner {
private val innerName = "Inner"
fun display() {
println("Inner Name: $innerName")
println("Outer Name: ${this@Outer.outerName}")
}
}
}
fun main() {
val obj = Outer().Inner()
obj.display()
}
Output:
Inner Name: Inner
Outer Name: Outer
| Feature | Nested Class | Inner Class |
|---|---|---|
| Keyword | Defined normally | Declared using inner |
| Outer Class Reference | Does not hold a reference | Holds a reference |
| Access to Outer Members | Cannot access outer members | Can access outer members (even private ones) |
| Object Creation | Outer.Nested() |
Outer().Inner() |
| Analogy in Java | Static nested class | Non-static inner class |
inner keyword. It cannot access members of the outer class.inner keyword. It has access to members of the outer class instance.this@OuterClassName.memberName.inner class has full access to all members of its outer class.this@OuterClass to access outer members explicitly.