大家好,我是William李梓峰,欢迎加入我的Kotlin学习之旅。
今天是我学习 Kotlin 的第十一天,内容是 Visibility Modifiers - 可见性修饰符。
官方文档:
Visibility Modifiers - 可见性修饰符
Classes, objects, interfaces, constructors, functions, properties and their setters can have visibility modifiers. (Getters always have the same visibility as the property.)
类、对象、接口、构造器、函数、属性还有属性的 setter,都可以设置“可见性修饰符”。(getter 的可见性修饰符总是与属性的看齐。)
There are four visibility modifiers in Kotlin: private
, protected
, internal
and public
. The default visibility, used if there is no explicit modifier, is public
.
Kotlin 总共有四种可见性修饰符:‘私有’、‘保护’、‘内置’ 和 ‘公有’。如果你没有显式地写可见性修饰符,那么默认就是用 ‘public’。(跟 Java 默认用的是 ‘default’ 不一样)
Below please find explanations of these for different type of declaring scopes.
下面请查看不同声明域的解释。
Packages - 包级域
Functions, properties and classes, objects and interfaces can be declared on the "top-level", i.e. directly inside a package:
函数、属性、类、对象和接口都可以顶级声明,也就是在包内独立声明:
// file name: example.kt
package foo // 包 foo
fun baz() {} // baz() 顶级方法
class Bar {} // 顶级类 Bar
- If you do not specify any visibility modifier,
public
is used by default, which means that your declarations will be visible everywhere; - If you mark a declaration
private
, it will only be visible inside the file containing the declaration; - If you mark it
internal
, it is visible everywhere in the same module; -
protected
is not available for top-level declarations. - 如果你没有指定任何可见性修饰符,‘public’ 就是默认指定的了(上面讲过了)
- 如果你写了一个 ‘private’,它就只能在文件内部可见。(不能被别的文件
import) - 如果你写了个 ‘internal’,它就只能在模块内部可见。(模块是啥?)
- ‘protected’ 不能用在顶级声明上。
Examples:
// 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
Classes and Interfaces - 类级域和接口级域
For members declared inside a class:
对于声明类的成员来说:
-
private
means visible inside this class only (including all its members); -
protected
--- same asprivate
+ visible in subclasses too; -
internal
--- any client inside this module who sees the declaring class sees itsinternal
members; -
public
--- any client who sees the declaring class sees itspublic
members. - ‘private’,即只能在类的内部可见(同样对类的其他成员可见);
- ‘protected’,即包含了 ‘private’ 的功能,同时还能对子类可见;
- ‘internal’,即对任何调用方,只要是在这个模块内的都可见。
- ‘public’,即对任何调用方都可见。
NOTE for Java users: outer class does not see private members of its inner classes in Kotlin.
注意, Java 开发者在玩 Kotlin 的时候请注意:外部类不可以看见其内部类的私有成员。(不太理解这句话什么意思,等以后介绍 Java 集成 Kotlin的时候再细细体会,现在别纠结,重点还是理解上面四个可见性修饰符的定义,毕竟跟 Java 的有点不同,尤其是多了一个支持模块化的 ‘internal’。)
If you override a protected
member and do not specify the visibility explicitly, the overriding member will also have protected
visibility.
如果你复写了一个 ‘protected’ 的成员,并且没有显式地重新指定一个可见性修饰符,那么复写后的成员还是 ‘protected’ 的。
Examples:
open class Outer {
private val a = 1 // 只有Outer内部可见
protected open val b = 2 // 只有Outer内部和子类可见
internal val c = 3 // 模块内可见
val d = 4 // public by default // 全世界都可见
protected class Nested { // 内部类首次登场
public val e: Int = 5 // 内部类在后面有介绍,这里先不管
}
}
class Subclass : Outer() { // 继承了 Outer 类
// a is not visible
// b, c and d are visible
// Nested and e are visible
override val b = 5 // 'b' is protected
}
class Unrelated(o: Outer) { // 构造器形参写了 Outer 类的 o 对象
// 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
}
Constructors - 构造器级域
To specify a visibility of the primary constructor of a class, use the following syntax (note that you need to add an explicit constructor{: .keyword } keyword):
主要构造器的可见性修饰符需要在构造器前面写:
class C private constructor(a: Int) { ... } // 私有构造器参上
Here the constructor is private. By default, all constructors are public
, which effectively amounts to them being visible everywhere where the class is visible (i.e. a constructor of an internal
class is only visible within the same module).
这里的构造器是私有的。默认情况下,所有的构造器都是 ‘public’ 的,这样子意味着世界上任何一个角落都可以访问这些构造器。(一个 ‘internal’的类的构造器仅仅可以在其模块中访问,什么是模块?)
Local declarations - 局部声明
Local variables, functions and classes can not have visibility modifiers.
局部变量,局部函数,局部类不可以有任何可见性修饰符。
Modules - 模块
The internal
visibility modifier means that the member is visible with the same module. More specifically,
a module is a set of Kotlin files compiled together:
‘internal’ 意思就是其成员在同一个模块下都可见。更具体地说,一个模块有一系列的 Kotlin 文件编译在一起:
an IntelliJ IDEA module;
a Maven or Gradle project;
a set of files compiled with one invocation of the <kotlinc> Ant task.
一个 IntelliJ IDEA 模块
一个Maven或Gradle工程
一些文件,它们用 Ant task 编译在一起