# 可見性標識符
類、對象、接口、構造器、函數、屬性和它們的 setter 都可以有_可見性標識符_。(getter 始終有與屬性相同的可見性)Kotlin 中有四種可見性標識符`private`、 `protected`、 `internal` 和 `public`。如果沒有明確地標識符,默認的可見性是 `public`。
下面請為聲明作用域的不同類型的說明。
## 包
函數、屬性和類、對象和接口可以被聲明在“頂層”,意即直接在某個包內:
``` kotlin
// 文件名: example.kt
package foo
fun baz() {}
class Bar {}
```
* 如果你不指定可見性標識符,`public` 就會被默認使用,意思就是你的聲明將在任何地方可見;
* 如果你標記一個聲明 `private`,它將僅在包含聲明的文件中可見;
* 如果你標記它為 `internal`,則它在相同的模塊中的任何地方可見;
* `protected` 在頂層聲明中無效。
示例:
``` kotlin
// 文件名: example.kt
package foo
private fun foo() {} // 在 example.kt 中可見
public var bar: Int = 5 // 屬性在任何地方可見
private set // setter 只在 example.dt 中可見
internal val baz = 6 // 在相同的模塊中可見
```
## 類和接口
當在類內部聲明時:
* `private` 的意思是只在類內部可見(包括它的所有成員);
* `protected` —— 與 `private` 相同 + 子類可也可見;
* `internal` —— *在模塊內部* 的終端,只要能看到所聲明的類就能看到它的 `internal` 成員;
* `public` —— 能看到所聲明的類的終端就能看到它的 `public` 成員。
Java 用戶*注意*:在 Kotlin 中類之外看不到它內部類的私有成員。
示例:
``` kotlin
open class Outer {
private val a = 1
protected val b = 2
internal val c = 3
val d = 4 // public 為默認
protected class Nested {
public val e: Int = 5
}
}
class Subclass : Outer() {
// a 不可見
// b、c 和 d 可見
// Nested 和 e 可見
}
class Unrelated(o: Outer) {
// o.a、o.b 不可見 are not visible
// o.c 和 o.d 可見(相同模塊)
// Outer.Nested 不可見,而且 Nested::e 也不可見
}
```
### 構造器
要指定某個類的主構造器的可見性,使用下面的語法(注意你需要加入一個明確的 `constructor` 關鍵字):
``` kotlin
class C private constructor(a: Int) { ... }
```
這里的構造器是私有的。默認情況下所有的構造器都是 `public`,只要類可見它們在任何地方都是可見的(意即一個 `internal` 類的構造器僅僅在相同模塊中可見)
### 局部聲明
局部變量、函數和類不能有可見性標識符。
## 模塊
`internal` 可見性標識符的意思是其成員在相同模塊中可見。更具體地說,一個模塊是一系列 Kotlin 文件相互編譯的:
* 一個 IntelliJ IDEA 模塊;
* 一個 Maven 或 Gradle 項目;
* Ant 任務一次調用的一系列編譯文件。