In Kotlin, just like If-else, we can define classes within classes. This concept is called nested classes and inner classes. There is a difference between them, they both serve a unique purpose. So, in this tutorial, we discuss nested vs. inner classes in Kotlin, including how to use them with simple code examples.
Nested vs Inner Classes in Kotlin: Basic Guide & Examples
Nested classes in Kotlin:
A class defined within another class without an inner keyword is a nested class. The nested class does not hold a reference to its outer class though it behaves like a Static class. It does not have direct access to its outer class member variables and functions. The main purpose of a nested class is to group the same type of functionality within the same class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
class SampleOuterClass { private val sampleOuterClassString = "I am from Outer Class" // Nested Class (Without 'inner' keyword) class SampleNestedClass { fun printMessage(): String { return "I am from Nested Class" // Cannot access outerVariable } } } fun main() { // Accessing Nested Class val nested = SampleOuterClass.SampleNestedClass() println(nested.printMessage()) // Output: I am from Nested Class // This will throw error // Because nested class does not have access to outer class variables println(nested.sampleOuterClassString) // Ouput // Unresolved reference 'sampleOuterClassString'. } |
Code explanation:
We have created an outer class SampleOuterClass and within the class. We have created a Nested class. In the outer class, we have created a string variable sampleOuterClassString but the nested class cannot access this variable because of its limitations. Now in the main function, we are creating an object of a nested class with an outer class and calling the function.
Inner classes in Kotlin:
Inner classes are always defined with inner keywords within another class. Inner classes can access the outer class member variables and functions because they hold a reference to the outer class. If needed we can directly access outer class members using this@OuterClass reference.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class DemoOuterClass { val demoOuterVariable = "I am from Outer Class" // Inner Class (uses 'inner' keyword) inner class DemoOuterClass { fun DemoOuterClass(): String { return "I am from Inner Class, accessing: $demoOuterVariable" } } } fun main() { // Accessing Inner Class val outer = DemoOuterClass() val inner = outer.DemoOuterClass() println(inner.DemoOuterClass()) // Output: I am from Inner Class, accessing: I am from Outer Class println(outer.demoOuterVariable) // Output: I am from Outer Class } |
Conclusion:
Both nested class and inner class have different approaches. Nested classes cannot access outer class members whereas the inner class can access the outer class members. So it’s up to us. If you want a class with its out member variable and functions whose does not have access to outer support then a nested class is the best option. If you want to outer support then you must choose inner class.