Klasy zagnieżdżone (nested) i wewnętrzne (inner) w Kotlinie są stosowane do logicznego grupowania i enkapsulacji funkcjonalności wewnątrz klasy zewnętrznej.
Pomysł klas zagnieżdżonych pochodzi z Javy jako sposób na strukturyzację kodu i izolację komponentów pomocniczych wewnątrz klasy głównej. W Kotlinie składnia i podejście zostały odziedziczone z Javy, ale z ważnymi różnicami.
Głównym zadaniem jest poprawne oddzielanie klas pomocniczych tam, gdzie nie powinny istnieć poza kontekstem klasy zewnętrznej, ale jednocześnie wymagana jest różna stopień dostępu do członków klasy zewnętrznej. W Javie klasy zagnieżdżone są domyślnie klasami wewnętrznymi, w Kotlinie domyślnie są statyczne (nested).
W Kotlinie domyślnie deklaracja klasy wewnątrz innej tworzy klasę statyczną (nested), co oznacza, że ta klasa nie ma dostępu do członków klasy zewnętrznej. Aby uzyskać dostęp, używa się słowa kluczowego inner.
Przykład kodu:
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" } }
Kluczowe cechy:
class Nested) domyślnie nie ma odniesienia do instancji klasy zewnętrznej;inner class Inner) ma odniesienie i może uzyskiwać dostęp do członków klasy zewnętrznej, nawet do prywatnych;Czy klasa zagnieżdżona (nested) może uzyskiwać dostęp do prywatnej właściwości klasy zewnętrznej?
Nie, klasa zagnieżdżona (domyślnie) w Kotlinie jest statyczna i nie ma odniesienia do klasy zewnętrznej, więc nie ma dostępu do jej właściwości i metod.
Jaka jest różnica między klasami inner w Kotlinie a Javie?
W Javie klasa zagnieżdżona domyślnie nie jest statyczna i ma odniesienie do klasy zewnętrznej. W Kotlinie — przeciwnie; klasa zagnieżdżona jest statyczna, tylko klasa inner otrzymuje odniesienie do zewnętrznej instancji.
Czy można zadeklarować klasę wewnętrzną w obiekcie (object)?
Nie, klasa wewnętrzna (inner) nie może być zadeklarowana wewnątrz obiektu, ponieważ obiekt nie może być instancjonowany.
Programista deklaruje klasę inner, która nie używa właściwości klasy zewnętrznej:
class Container { inner class Helper { fun help() = "help" } }
Zalety:
Klasa jest łatwo dostępna z zewnętrznego obiektu.
Wady:
Użycie klasy inner do realizacji dostępu do prywatnego stanu klasy zewnętrznej:
class Auth { private var token: String = "" inner class TokenManager { fun updateToken(new: String) { token = new } } }
Zalety:
Wady: