Verschachtelte (nested) und innere (inner) Klassen in Kotlin werden verwendet, um Funktionalitäten innerhalb einer äußeren Klasse logisch zu gruppieren und zu kapseln.
Die Idee der verschachtelten Klassen stammt aus Java als Mittel zur Strukturierung von Code und zur Isolierung von Hilfskomponenten innerhalb der Hauptklasse. In Kotlin ist die Syntax und Herangehensweise von Java übernommen, aber mit wichtigen Unterschieden.
Die Hauptaufgabe besteht darin, Hilfsklassen dort abzutrennen, wo sie nicht außerhalb des Kontexts der äußeren Klasse existieren sollten, aber dennoch unterschiedliche Zugriffsgrade auf die Mitglieder der äußeren Klasse erforderlich sind. In Java ist eine verschachtelte Klasse standardmäßig eine innere Klasse, während in Kotlin der Standard eine verschachtelte (statische) Klasse ist.
In Kotlin erstellt die Deklaration einer Klasse innerhalb einer anderen standardmäßig eine statische (nested) Klasse, das heißt, diese Klasse hat keinen Zugriff auf die Mitglieder der äußeren Klasse. Um Zugriff zu erhalten, wird das Schlüsselwort inner verwendet.
Beispielcode:
class Outer { private val secret = "outside" class Nested { fun call() = "nested: kein Zugriff auf Outer.secret" } inner class Inner { fun call() = "inner: kann auf $secret zugreifen" } }
Wichtige Besonderheiten:
class Nested) hat standardmäßig keinen Verweis auf eine Instanz der äußeren Klasse;inner class Inner) hat einen Verweis und kann auf die Mitglieder der äußeren Klasse, sogar auf private, zugreifen;Kann eine verschachtelte (nested) Klasse auf privates Attribut der äußeren Klasse zugreifen?
Nein, die verschachtelte Klasse (standardmäßig) in Kotlin ist statisch und enthält keinen Verweis auf die äußere Klasse, daher hat sie keinen Zugriff auf deren Eigenschaften und Methoden.
Was ist der Unterschied zwischen inner-Klassen in Kotlin und Java?
In Java ist eine verschachtelte Klasse standardmäßig nicht static und hat einen Verweis auf die äußere. In Kotlin hingegen; die verschachtelte Klasse ist static, nur die innere Klasse erhält einen Verweis auf die äußere Instanz.
Kann eine innere Klasse in einem Objekt (object) deklariert werden?
Nein, die innere Klasse (inner) kann nicht innerhalb eines Objekts deklariert werden, da ein Objekt nicht instanziiert werden kann.
Ein Entwickler deklariert eine innere Klasse, die die Eigenschaften der äußeren Klasse nicht verwendet:
class Container { inner class Helper { fun help() = "help" } }
Vorteile:
Die Klasse kann leicht aus dem äußeren Objekt abgerufen werden.
Nachteile:
Verwendung einer inneren Klasse zur Implementierung des Zugriffs auf den privaten Zustand der äußeren Klasse:
class Auth { private var token: String = "" inner class TokenManager { fun updateToken(new: String) { token = new } } }
Vorteile:
Nachteile: