# 可见性标识符
类、对象、接口、构造器、函数、属性和它们的 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 任务一次调用的一系列编译文件。