ヴィジビリティ修飾子
クラス、オブジェクト、インターフェース、コンストラクタ、関数、プロパティとそのセッターに対して、ヴィジビリティを設定することができます。
(ゲッターのヴィジビリティはプロパティのヴィジビリティと同じものになります)
Kotlinには、4種類のヴィジビリティ修飾子があります。
- private
- protected
- internal
- public
明示的にヴィジビリティ修飾子を設定しない場合、デフォルトのヴィジビリティ修飾子は「public」になります。
パッケージ
トップレベルに宣言されたクラス、オブジェクト、インターフェース、関数、プロパティのヴィジビリティは次の表のようになります。
ヴィジビリティ | どこから見えるか |
---|---|
public(デフォルト) | どこからでも参照可能 |
private | 同じファイル内のみ参照可能 |
internal | 同じモジュール内のみ参照可能 |
protected | トップレベルで宣言したものには使用できない |
example.kt
package visibilitytest
// getterにはどこからでも参照できる
var num: Int = 123
// setterはこのファイル内でしか参照できない
private set(value) {
if (value < 0) {
println("${value} は無効です")
return
}
field = value
}
// internalなので、この関数は同じモジュールからであれば参照できる
internal fun assignNum(value: Int) {
num = value
}
main.kt
package visibilitytest
fun main(args: Array) {
println("num = ${num}")
assignNum(-321)
// numのsetterはprivateなので、以下のコードはビルドエラー
// num = -321
}
num = 123
-321 は無効です
クラス/インターフェースメンバー
クラスとインターフェースのメンバーのヴィジビリティは次の表のようになります.
ヴィジビリティ | どこから見えるか |
---|---|
private | 同じクラス/インターフェース(のメンバー)から参照可能 |
protected | privateと同じ範囲+サブクラス(のメンバー)から参照可能 |
internal | internalなメンバーを持つクラスが宣言されているモジュール内から参照可能 |
public(デフォルト) | どこからでも参照可能 |
example.kt
package visibilitytest
import java.nio.DoubleBuffer
open class Person(name: String) {
var name = name
protected set(value) {
if (value.isEmpty()) {
println("Empty name is invalid")
return
}
field = value
}
internal fun printName() = println("Name is ${name}.")
}
class Student(name: String, score: Double) : Person(name) {
var score = score
fun toUpperCaseName() {
// name のsetterはprotectedなので、サブクラスではアクセルできる
name = name.toUpperCase()
}
}
class PersonDescriber(someone: Person) {
val someone = someone
fun describe() {
// printName はinternalなので、同じモジュール内では参照できる
someone.printName()
}
}
main.kt
import visibilitytest.Student
import visibilitytest.PersonDescriber
fun main(args: Array) {
val student = Student("suzuki taro", 80.0)
println("student is ${student.name}")
student.toUpperCaseName()
val desc = PersonDescriber(student)
desc.describe()
}
student is suzuki taro
Name is SUZUKI TARO.
プライマリコンストラクタ
プライマリコンストラクタにヴィジビリティを設定したい場合、明示的にconstructorキーワードをつける必要があります。
example.kt
package visibilitytest
// プライマリコンストラクタにprotectedを設定
open class Person protected constructor(name: String) {
var name = name
protected set(value) {
if (value.isEmpty()) {
println("Empty name is invalid")
return
}
field = value
}
internal fun printName() = println("Name is ${name}.")
}
class Student(name: String, score: Double) : Person(name) {
var score = score
fun toUpperCaseName() {
// name のsetterはprotectedなので、サブクラスではアクセルできる
name = name.toUpperCase()
}
}
class PersonDescriber(someone: Person) {
val someone = someone
fun describe() {
// printName はinternalなので、同じモジュール内では参照できる
someone.printName()
}
}
main.kt
import visibilitytest.Person
import visibilitytest.Student
import visibilitytest.PersonDescriber
fun main(args: Array) {
val student = Student("suzuki taro", 80.0)
println("student is ${student.name}")
student.toUpperCaseName()
val desc = PersonDescriber(student)
desc.describe()
// Personのプライマリコンストラクタはprotectedであり、ここからはアクセスできない
// そのため、直接Personをインスタンス化することはできない
// 以下のコードはビルドエラー
// val person = Person("someone")
}