ProgrammingAndroid開発者

Kotlinの可視性修飾子(internal、private、protected、public)はどのように機能しますか?クラス、関数、プロパティ、オブジェクト、トップレベル関数およびファイルにおいて、異なるコンテキストでの修飾子の違いは何ですか?

Hintsage AIアシスタントで面接を突破

回答

Kotlinには次の可視性修飾子があります:

  • public(デフォルト):要素はどこでも見えます。
  • internal:要素は同一モジュール内で見えます(jar/gradleモジュールなど)。
  • protected:クラス内およびそのサブクラス内でのみ見えます。
  • private:ファイルまたはクラス内でのみ見えます。

特徴:

  • トップレベルの関数、プロパティ、およびクラスの場合:privateはファイルの境界内でアクセスを制限し、internalはモジュール内で、public/protectedはクラスの外では意味がありません。
  • クラスのメンバーの場合:privateはこのクラス内でのみ、protectedはサブクラスも含め、internalpublicは上記の通りです。
  • オブジェクト/コンパニオンオブジェクト内では:クラスと同様です。
class MyClass { private val secret = "hidden" protected val id = 42 internal fun foo() {} public fun bar() {} } internal fun moduleFunc() {} private fun fileOnlyFunc() {}

わかりにくい質問

"トップレベル関数はprotectedにできますか?もしできるなら—それはどう機能しますか?できない場合—なぜですか?"

回答: いいえ、トップレベル関数はprotectedにできません。なぜなら、そのアクセスレベルに属するクラスが存在しないからです。コンパイラーがこれを処理し、コンパイルエラーが発生します。

protected fun magic() {} // エラー:トップレベル関数に対するprotected修飾子は許可されていません

このテーマの微妙な点を知らないことによる実際のエラーの例


物語

fintechアプリケーションで、internal修飾子がモジュール内のすべての要素にアクセスを許可することを忘れました。その結果、リファクタリング時に一部のロジックを別のgradleモジュールに移行したため、データへのアクセスができなくなりましたが、開発者は古いテストでコンパイルエラーが発生しなかったため、すぐには気づきませんでした。


物語

マルチプラットフォームプロジェクトで、コンパニオンオブジェクト内のprivateプロパティとして機密データを定義しました。それらのデータはシリアライズされ、輸出を制限するアノテーションを使用せずにvalとして宣言されたため、reflectionを介してアクセス可能になりました。


物語

モバイルプロジェクトの開始時に、トップレベルの関数にprivateを使用し、パートナークラスがアクセスできないようにすると考えていました。しかし、ユーティリティ用のファイル内でそれらの関数が全員に見えてしまい、情報漏洩のリスクやビジネスロジックでの予期しない利用が発生しました。