大家好,我是William李梓峰,歡迎加入我的Kotlin學(xué)習(xí)之旅。
今天是我學(xué)習(xí) Kotlin 的第十一天,內(nèi)容是 Visibility Modifiers - 可見(jiàn)性修飾符。
官方文檔:
Visibility Modifiers - 可見(jiàn)性修飾符
Classes, objects, interfaces, constructors, functions, properties and their setters can have visibility modifiers. (Getters always have the same visibility as the property.)
類、對(duì)象、接口、構(gòu)造器、函數(shù)、屬性還有屬性的 setter,都可以設(shè)置“可見(jiàn)性修飾符”。(getter 的可見(jiàn)性修飾符總是與屬性的看齊。)
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 總共有四種可見(jiàn)性修飾符:‘私有’、‘保護(hù)’、‘內(nèi)置’ 和 ‘公有’。如果你沒(méi)有顯式地寫可見(jiàn)性修飾符,那么默認(rèn)就是用 ‘public’。(跟 Java 默認(rèn)用的是 ‘default’ 不一樣)
Below please find explanations of these for different type of declaring scopes.
下面請(qǐng)查看不同聲明域的解釋。
Packages - 包級(jí)域
Functions, properties and classes, objects and interfaces can be declared on the "top-level", i.e. directly inside a package:
函數(shù)、屬性、類、對(duì)象和接口都可以頂級(jí)聲明,也就是在包內(nèi)獨(dú)立聲明:
// file name: example.kt
package foo // 包 foo
fun baz() {} // baz() 頂級(jí)方法
class Bar {} // 頂級(jí)類 Bar
- If you do not specify any visibility modifier,
publicis 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; -
protectedis not available for top-level declarations. - 如果你沒(méi)有指定任何可見(jiàn)性修飾符,‘public’ 就是默認(rèn)指定的了(上面講過(guò)了)
- 如果你寫了一個(gè) ‘private’,它就只能在文件內(nèi)部可見(jiàn)。(不能被別的文件
import) - 如果你寫了個(gè) ‘internal’,它就只能在模塊內(nèi)部可見(jiàn)。(模塊是啥?)
- ‘protected’ 不能用在頂級(jí)聲明上。
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 - 類級(jí)域和接口級(jí)域
For members declared inside a class:
對(duì)于聲明類的成員來(lái)說(shuō):
-
privatemeans 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 itsinternalmembers; -
public--- any client who sees the declaring class sees itspublicmembers. - ‘private’,即只能在類的內(nèi)部可見(jiàn)(同樣對(duì)類的其他成員可見(jiàn));
- ‘protected’,即包含了 ‘private’ 的功能,同時(shí)還能對(duì)子類可見(jiàn);
- ‘internal’,即對(duì)任何調(diào)用方,只要是在這個(gè)模塊內(nèi)的都可見(jiàn)。
- ‘public’,即對(duì)任何調(diào)用方都可見(jiàn)。
NOTE for Java users: outer class does not see private members of its inner classes in Kotlin.
注意, Java 開發(fā)者在玩 Kotlin 的時(shí)候請(qǐng)注意:外部類不可以看見(jiàn)其內(nèi)部類的私有成員。(不太理解這句話什么意思,等以后介紹 Java 集成 Kotlin的時(shí)候再細(xì)細(xì)體會(huì),現(xiàn)在別糾結(jié),重點(diǎn)還是理解上面四個(gè)可見(jiàn)性修飾符的定義,畢竟跟 Java 的有點(diǎn)不同,尤其是多了一個(gè)支持模塊化的 ‘internal’。)
If you override a protected member and do not specify the visibility explicitly, the overriding member will also have protected visibility.
如果你復(fù)寫了一個(gè) ‘protected’ 的成員,并且沒(méi)有顯式地重新指定一個(gè)可見(jiàn)性修飾符,那么復(fù)寫后的成員還是 ‘protected’ 的。
Examples:
open class Outer {
private val a = 1 // 只有Outer內(nèi)部可見(jiàn)
protected open val b = 2 // 只有Outer內(nèi)部和子類可見(jiàn)
internal val c = 3 // 模塊內(nèi)可見(jiàn)
val d = 4 // public by default // 全世界都可見(jiàn)
protected class Nested { // 內(nèi)部類首次登場(chǎng)
public val e: Int = 5 // 內(nèi)部類在后面有介紹,這里先不管
}
}
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) { // 構(gòu)造器形參寫了 Outer 類的 o 對(duì)象
// 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 - 構(gòu)造器級(jí)域
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):
主要構(gòu)造器的可見(jiàn)性修飾符需要在構(gòu)造器前面寫:
class C private constructor(a: Int) { ... } // 私有構(gòu)造器參上
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).
這里的構(gòu)造器是私有的。默認(rèn)情況下,所有的構(gòu)造器都是 ‘public’ 的,這樣子意味著世界上任何一個(gè)角落都可以訪問(wèn)這些構(gòu)造器。(一個(gè) ‘internal’的類的構(gòu)造器僅僅可以在其模塊中訪問(wèn),什么是模塊?)
Local declarations - 局部聲明
Local variables, functions and classes can not have visibility modifiers.
局部變量,局部函數(shù),局部類不可以有任何可見(jiàn)性修飾符。
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’ 意思就是其成員在同一個(gè)模塊下都可見(jiàn)。更具體地說(shuō),一個(gè)模塊有一系列的 Kotlin 文件編譯在一起:
an IntelliJ IDEA module;
a Maven or Gradle project;
a set of files compiled with one invocation of the <kotlinc> Ant task.
一個(gè) IntelliJ IDEA 模塊
一個(gè)Maven或Gradle工程
一些文件,它們用 Ant task 編譯在一起