Kotlin アクセス修飾子(Visibility modifiers)

概要

アクセス修飾子(Visibility Modifier)は、オブジェクトを公開する範囲を定める役割を持つ。

アクセス修飾子の種類

Kotlinではprivateprotectedinternalpublicのアクセス修飾子を提供し、変数、関数、クラスメンバーなどの参照範囲を指定する。

種類 説明
public Kotlinのデフォルトのアクセス修飾子で、どこからでもアクセスできる。
private 該当ファイル(.kt)またはクラス内でのみアクセスできる。
protected クラス内および子クラスからアクセスできる。top-levelでは宣言できない。
internal 同じモジュール内であればどこからでもアクセスできる。

アクセス修飾子を何も付けない場合はpublicとして宣言される。

アクセス修飾子を持てる要素にはclassobjectinterfaceconstructorfunctionpropertyなどがある。ローカル変数、ローカル関数、ローカルクラスにはアクセス修飾子を宣言できない。

パッケージ(Packages)

関数、プロパティ、クラス、オブジェクト、インターフェースは、パッケージ内部で直接「トップレベル(top-level)」に宣言できる。

// file name: example.kt
package foo

fun baz() { ... } // example.ktファイル内でのみアクセスできる。
class Bar { ... } //

パッケージレベルで定義されるオブジェクトのアクセス修飾子には、次の意味がある。

  • アクセス修飾子を宣言しない場合、publicがデフォルトになり、どこからでもアクセスできる。
  • privateとして宣言すると、ファイル(.kt)内でのみアクセスできる。
  • internalとして宣言すると、プロジェクトのモジュール内なら誰でもアクセスできる。
  • protectedはトップレベル(top-level)には宣言できない。

Kotlinでは、次のようにトップレベル(Top-level)の関数またはプロパティにアクセス修飾子を宣言できる。

// file name: example.kt
package foo

private fun foo() { ... } // example.ktファイル内でのみアクセスできる。

public var bar: Int = 5 // このプロパティはどこからでもアクセスできる。
    private set         // example.ktファイル内ではsetterにアクセスできる。

internal val baz = 6    // 同一モジュールではアクセスできる。

クラスとインターフェースのメンバー(Class members)

クラスとインターフェースの中に宣言されるメンバーに使うアクセス修飾子には、次の意味がある。

  • public: どこからでもアクセスできる。
  • private: クラス内部でのみアクセスできる。
  • protected: クラス内部と継承したオブジェクトからアクセスできる。
  • internal: プロジェクトのモジュール内の誰でもアクセスできる。

次の例のように使用できる。

open class Outer {
    private val a = 1
    protected open val b = 2
    internal open val c = 3
    val d = 4  // デフォルトで`public`として宣言される。

    protected class Nested {
        public val e: Int = 5
    }
}

class Subclass : Outer() { // Outerを継承したオブジェクト
    // 'a'変数にはアクセスできない。
    // 'b'、'c'、'd'にはアクセスできる。
    // `Nested`と'e'にアクセスできる。

    override val b = 5   // 'b'は'protected'として宣言されている。
    override val c = 7   // 'c'は'internal'として宣言されている。
}

class Unrelated(o: Outer) {
    // 'o.a'と'o.b'にはアクセスできない。
    // 'o.c'と'o.d'にはアクセスできる。(同じモジュール)
    // 'Outer.Nested'にはアクセスできず、'Nested::e'にもアクセスできない。
}

コンストラクタのアクセス修飾子

コンストラクタにアクセス修飾子を付けない場合、すべてのコンストラクタは公開(public)として宣言されるため、どこからでもクラスにアクセスできる。privateを付けるとクラス内でのみアクセスでき、外部から生成できなくなる。internalを付けるとモジュール内でのみアクセスできる。

注意: コンストラクタにアクセス修飾子を宣言するには、キーワード(constructor)を明示的に付ける必要がある。

class C private constructor(a: Int) { ... }

ここでは、コンストラクタは非公開(private)として宣言され、クラス内部ではアクセスできる。

モジュール

ここでinternalにおける同じモジュールとは、公式ドキュメントによると次のとおりである。

  • An IntelliJ IDEA module.
  • A Maven project.
  • A Gradle source set (with the exception that the test source set can access the internal declarations of main).
  • A set of files compiled with one invocation of the <kotlinc> Ant task.

つまり、同じプロジェクト内ではinternal修飾子にアクセスできると考えればよい。

参考