Kotlin Nested class and Inner class (original) (raw)

Last Updated : 08 Feb, 2023

Nested Class

In Kotlin, you can define a class inside another class, which is known as a nested class. Nested classes have access to the members (fields and methods) of the outer class.

Here is an example of a nested class in Kotlin:

Kotlin `

class Car { var make: String var model: String var year: Int

inner class Engine {
    var horsepower: Int = 0
    var cylinders: Int = 0

    fun getEngineInfo(): String {
        return "$horsepower horsepower, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>c</mi><mi>y</mi><mi>l</mi><mi>i</mi><mi>n</mi><mi>d</mi><mi>e</mi><mi>r</mi><mi>s</mi><mi>c</mi><mi>y</mi><mi>l</mi><mi>i</mi><mi>n</mi><mi>d</mi><mi>e</mi><mi>r</mi><mi>s</mi><mo separator="true">,</mo><mi>i</mi><mi>n</mi><mi>a</mi></mrow><annotation encoding="application/x-tex">cylinders cylinders, in a </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">cy</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">in</span><span class="mord mathnormal">d</span><span class="mord mathnormal" style="margin-right:0.03588em;">erscy</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">in</span><span class="mord mathnormal">d</span><span class="mord mathnormal">ers</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">ina</span></span></span></span>make $model"
    }
}

fun getInfo(): String {
    return "$make <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi><mi>o</mi><mi>d</mi><mi>e</mi><mi>l</mi><mo separator="true">,</mo><mi>y</mi><mi>e</mi><mi>a</mi><mi>r</mi></mrow><annotation encoding="application/x-tex">model, year </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">m</span><span class="mord mathnormal">o</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">ye</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span></span></span></span>year"
}

}

fun main() { val myCar = Car() myCar.make = "Toyota" myCar.model = "Camry" myCar.year = 2020

val engine = myCar.Engine()
engine.horsepower = 250
engine.cylinders = 6

println(engine.getEngineInfo())

}

`

Output:

250 horsepower, 6 cylinders, in a Toyota Camry

A class is declared within another class then it is called a nested class. By default nested class is static so we can access the nested class property or variables using dot(.) notation without creating an object of the class.
Syntax of declaration:

class outerClass { ............ // outer class properties or member function

  class nestedClass { 
        ..........
        // inner class properties or member function
  }

}

Note: Nested class can't access the members of the outer class, but we can access the property of nested class from the outer class without creating an object for nested class.

Kotlin program of accessing nested class properties:

Kotlin `

// outer class declaration class outerClass { var str = "Outer class" // nested class declaration class nestedClass { val firstName = "Praveen" val lastName = "Ruhil" } } fun main(args: Array) { // accessing member of Nested class print(outerClass.nestedClass().firstName) print(" ") println(outerClass.nestedClass().lastName) }

`

Output:

Praveen Ruhil

In Kotlin, to access the member function of nested class, we need to create the object for nested class and call the member function using it.

Kotlin program of accessing nested class member function:

Kotlin `

// outer class declaration class outerClass { var str = "Outer class" // nested class declaration class nestedClass { var s1 = "Nested class" // nested class member function fun nestfunc(str2: String): String { var s2 = s1.plus(str2) return s2 } } } fun main(args: Array) { // creating object of Nested class val nested = outerClass.nestedClass() // invoking the nested member function by passing string var result = nested.nestfunc(" member function call successful") println(result) }

`

Output:

Nested class member function call successful

Comparison with Java

Kotlin classes are much similar to Java classes when we think about the capabilities and use cases, but not identical. Nested in Kotlin is similar to a static nested class in Java and the Inner class is similar to a non-static nested class in Java.

Kotlin Inner Class

When we can declare a class inside another class using the keyword inner then it is called inner class. With the help of the inner class, we can access the outer class property inside the inner class.

class outerClass { ............ // outer class properties or member function

  **inner** class innerClass { 
        ..........
        // inner class properties or member function
  }

}

In the below program we are trying to access str from the inner class member function. But it does not work and gives a compile-time error.
Kotlin program of inner class:

Kotlin `

// outer class declaration class outerClass { var str = "Outer class" // innerClass declaration without using inner keyword class innerClass { var s1 = "Inner class" fun nestfunc(): String { // can not access the outer class property str var s2 = str return s2 } } } // main function fun main(args: Array) { // creating object for inner class val inner= outerClass().innerClass() // inner function call using object println(inner.nestfunc()) }

`

Output:

Error:(9, 22) Kotlin: Unresolved reference: str

First, use the inner keyword in front of the inner class. Then, create an instance of the outer class else we can’t use inner classes.

Kotlin `

// outer class declaration class outerClass { var str = "Outer class" // innerClass declaration with using inner keyword inner class innerClass { var s1 = "Inner class" fun nestfunc(): String { // can access the outer class property str var s2 = str return s2 } } } // main function fun main(args: Array) { // creating object for inner class val inner= outerClass().innerClass() // inner function call using object println(inner.nestfunc()+" property accessed successfully from inner class ") }

`

Output:

Outer class property accessed successfully from inner class

Advantages or Disadvantages:

Advantages of using nested and inner classes in Kotlin:

  1. Encapsulation: Nested and inner classes allow you to group related functionality together and keep it separate from the rest of the code, improving code organization and readability.
  2. Reusability: Nested and inner classes can be reused within the same class or across multiple classes, making it easier to write more maintainable code.
  3. Accessibility: Inner classes have access to the members of the outer class, making it easier to share data between them and reducing code duplication.

Disadvantages of using nested and inner classes in Kotlin:

  1. Complexity: Adding nested and inner classes can make the code more complex and harder to understand, especially if there are multiple levels of nesting or if inner classes are used excessively.
  2. Performance: Using nested and inner classes can slow down the performance of your code, especially if they are heavily used or if they are nested to many levels deep.
  3. Debugging: Debugging nested and inner classes can be challenging, especially if there are multiple levels of nesting or if inner classes are used excessively.
  4. Overall, it's important to use nested and inner classes in a balanced and appropriate way to take advantage of their benefits while avoiding their disadvantages.