5.1.5 可见性修饰符

原文链接: https://kotlinlang.org/docs/visibility-modifiers.html

5.1.5 可见性修饰符

类、对象、接口、构造器和函数,以及属性和它们的 setter,都可以有可见性修饰符。getter 的可见性始终与其属性相同。

Kotlin 中有四个可见性修饰符:private、protected、internal 和 public。默认可见性是 public。

本页将介绍这些修饰符如何应用于不同类型的声明作用域。

包

函数、属性、类、对象和接口可以在「顶层」直接声明在包中:

1
2
3
4
5
// file name: example.kt
package foo

fun baz() { ... }
class Bar { ... }
  • 如果你不使用可见性修饰符,默认使用 public,这意味着你的声明在任何位置都可见。
  • 如果你把声明标记为 private,它只在包含该声明的文件内可见。
  • 如果你把它标记为 internal,它在同一模块内的任何位置都可见。
  • protected 修饰符不能用于顶层声明。

要使用另一个包中可见的顶层声明,你需要导入它。

示例:

1
2
3
4
5
6
7
8
9
// file name: example.kt
package foo

private fun foo() { ... } // visible inside example.kt

public var bar: Int = 5 // property is visible everywhere
    private set         // setter is visible only in example.kt

internal val baz = 6    // visible inside the same module

类成员

对于在类内部声明的成员:

  • private 表示该成员只在本类内部可见(包括本类的所有成员)。
  • protected 表示该成员的可见性与标记为 private 时相同,但它在子类中也可见。
  • internal 表示本模块内任何能看到该声明类的客户端都能看到它的 internal 成员。
  • public 表示任何能看到该声明类的客户端都能看到它的 public 成员。

注意: 在 Kotlin 中,外层类看不到其内部类的 private 成员。

如果你重写了 protected 或 internal 成员,并且没有显式指定可见性,那么重写后的成员也具有与原成员相同的可见性。

示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
open class Outer {
    private val a = 1
    protected open val b = 2
    internal open val c = 3
    val d = 4  // public by default

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

class Subclass : Outer() {
    // a is not visible
    // b, c and d are visible
    // Nested and e are visible

    override val b = 5   // 'b' is protected
    override val c = 7   // 'c' is internal
}

class Unrelated(o: Outer) {
    // o.a, o.b are not visible
    // o.c and o.d are visible (same module)
    // Outer.Nested is not visible, and Nested::e is not visible either
}

构造器

使用以下语法指定类的主构造器的可见性:

注意: 你需要显式添加 constructor 关键字。

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

这里的构造器是 private。默认情况下,所有构造器都是 public,这实际上意味着:只要类可见,构造器就可见(也就是说,internal 类的构造器只在同一模块内可见)。

对于密封类,构造器默认是 protected。更多信息请参阅密封类。

局部声明

局部变量、函数和类不能有可见性修饰符。

模块

internal 可见性修饰符表示该成员在同一模块内可见。更具体地说,模块是一组一起编译的 Kotlin 文件,例如:

  • 一个 IntelliJ IDEA 模块。
  • 一个 Maven 项目。
  • 一个 Gradle 源集(例外情况是:test 源集可以访问 main 的 internal 声明)。