Nested and inner classes in Kotlin are used for logical grouping and encapsulation of functionality within an outer class.
The idea of nested classes came from Java as a way to structure code and isolate helper components within the main class. In Kotlin, the syntax and approach are inherited from Java, but with important differences.
The main task is to correctly separate helper classes where they should not exist outside the context of the outer class, while requiring varying degrees of access to the members of the outer class. In Java, a nested class is by default an inner class, whereas in Kotlin, a nested class is by default static.
In Kotlin, declaring a class inside another class by default creates a static (nested) class, meaning that this class does not have access to the members of the outer class. To gain access, the keyword inner is used.
Code example:
class Outer { private val secret = "outside" class Nested { fun call() = "nested: no access to Outer.secret" } inner class Inner { fun call() = "inner: can access $secret" } }
Key features:
class Nested) by default does not have a reference to the instance of the outer class;inner class Inner) has a reference and can access the members of the outer class, including private ones;Can a nested class access a private property of the outer class?
No, a nested class (by default) in Kotlin is static and does not contain a reference to the outer class, hence it does not have access to its properties and methods.
What is the difference between inner classes in Kotlin and Java?
In Java, a nested class is by default non-static and has a reference to the outer class. In Kotlin, on the contrary; a nested class is static, only an inner class obtains a reference to the outer instance.
Is it possible to declare an inner class in an object?
No, an inner class cannot be declared inside an object because an object cannot be instantiated.
A developer declares an inner class that does not use the properties of the outer class:
class Container { inner class Helper { fun help() = "help" } }
Pros:
The class is easy to obtain from the outer object.
Cons:
Using an inner class to implement access to private state of the outer class:
class Auth { private var token: String = "" inner class TokenManager { fun updateToken(new: String) { token = new } } }
Pros:
Cons: