Kotlinにおけるネストされたクラスと内部クラスは、外部クラスの内部での機能の論理的なグループ化とカプセル化に使用されます。
ネストされたクラスのアイデアは、Javaからのものであり、コードを構造化し、支援コンポーネントを主要クラスの内部に隔離する方法として来ています。Kotlinでは、文法とアプローチはJavaから引き継がれていますが、重要な違いがあります。
主な課題は、外部クラスのコンテキスト外で存在すべきでない支援クラスを適切に分離することですが、その際に外部クラスのメンバーへの異なるアクセスレベルが必要です。Javaでは、ネストされたクラスはデフォルトで内部クラスですが、Kotlinではデフォルトでネストされた(静的)クラスです。
Kotlinでは、デフォルトで別のクラス内でのクラスの宣言は静的(ネストされた)クラスを作成し、このクラスは外部クラスのメンバーへのアクセスを持ちません。アクセスを取得するにはinnerキーワードを使用します。
コードの例:
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" } }
主な特徴:
class Nested)はデフォルトで外部クラスのインスタンスへの参照を持たない;inner class Inner)は参照を持ち、外部クラスのメンバー、プライベートメンバーにもアクセスできる;ネストされた(nested)クラスは外部クラスのプライベートプロパティにアクセスできますか?
いいえ、Kotlinのネストされたクラス(デフォルト)は静的で、外部クラスへの参照を持たないため、そのプロパティやメソッドにアクセスできません。
KotlinとJavaの内部クラスの違いは何ですか?
Javaではネストされたクラスはデフォルトでstaticではなく、外部クラスへの参照を持ちますが、Kotlinでは逆で、ネストされたクラスはstaticであり、内部クラスのみが外部インスタンスへの参照を取得します。
オブジェクト(object)内に内部クラスを宣言できますか?
いいえ、内部クラス(inner)はobject内部に宣言できません。なぜなら、objectはインスタンス化できないからです。
開発者が外部クラスのプロパティを使用しない内部クラスを宣言:
class Container { inner class Helper { fun help() = "help" } }
メリット:
外部オブジェクトからクラスを簡単に取得できる。
デメリット:
外部クラスのプライベート状態へのアクセスを実現するために内部クラスを使用:
class Auth { private var token: String = "" inner class TokenManager { fun updateToken(new: String) { token = new } } }
メリット:
デメリット: