可見性修飾符#

以下是 Kotlin 中 Visibility Modifiers(可見性修飾符) 的教學,涵蓋 publicprivateprotectedinternal


1. 可見性修飾符概述#

修飾符列表#

修飾符定義範圍用法範圍
public預設可見性,所有地方都可以存取類別、屬性、方法
private僅在宣告的檔案或類別內部可見類別、屬性、方法
protected僅在類別和其子類別內部可見(僅適用於類別成員,不適用於頂層宣告)屬性、方法
internal僅在相同模組內部可見類別、屬性、方法

2. public(預設可見性)#

特性#

  1. public 是 Kotlin 的預設修飾符。
  2. 可在任何地方存取。

範例:public 修飾符#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Person {
    public var name: String = "Default Name" // 可省略 `public`
}

fun main() {
    val person = Person()
    println(person.name) // 輸出:Default Name
    person.name = "Alice"
    println(person.name) // 輸出:Alice
}

3. private#

特性#

  • 對於類別成員:只能在該類別內部存取。
  • 對於頂層宣告:只能在該檔案內部存取。

範例 1:類別內部的 private#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Person {
    private var age: Int = 18

    fun printAge() {
        println("Age: $age") // 內部可以存取
    }
}

fun main() {
    val person = Person()
    // println(person.age) // 錯誤:無法從外部存取 `private` 屬性
    person.printAge() // 輸出:Age: 18
}

範例 2:檔案內部的 private#

檔案名稱:Utils.kt

1
2
3
4
5
6
7
private fun secretFunction() { // 頂層宣告
    println("This is a private function.")
}

fun publicFunction() {
    secretFunction() // 可以在同檔案內部呼叫
}

檔案名稱:Main.kt

1
2
3
4
5
6
import Utils.publicFunction
// import Utils.secretFunction // 錯誤:`secretFunction` 無法從外部存取

fun main() {
    publicFunction()
}

4. protected#

特性#

  1. 僅適用於類別及其子類別,不適用於頂層宣告。
  2. 子類別內部可存取,但外部無法存取。

範例:protected 的使用#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
open class Animal {
    protected fun makeSound() {
        println("Some animal sound")
    }
}

class Dog : Animal() {
    fun bark() {
        makeSound() // 子類別內部可以存取
        println("The dog barks")
    }
}

fun main() {
    val dog = Dog()
    dog.bark()
    // dog.makeSound() // 錯誤:無法從外部存取 `protected` 方法
}

5. internal#

特性#

  1. 僅在同一模組內可見(模組通常是指一個編譯單位,如一個 Gradle 或 Maven 模組)。
  2. 不同模組中的程式碼無法存取 internal 成員。
  3. 適用於需要在模組內共享,但不希望暴露給模組外部的成員。

範例:internal 的使用#

檔案名稱:Person.kt

1
2
3
4
5
6
7
internal class Person {
    internal var name: String = "Default Name"

    internal fun printName() {
        println("Name: $name")
    }
}

檔案名稱:Main.kt(同模組)

1
2
3
4
fun main() {
    val person = Person()
    person.printName() // 輸出:Name: Default Name
}

檔案名稱:OtherModule.kt(不同模組)

1
// import com.example.Person // 錯誤:`Person` 是 `internal`,無法從外部模組存取

6. 各修飾符的對比表#

修飾符頂層函數或屬性類別及其成員
public全域可見(預設)全域可見(預設)
private僅限於同一檔案僅限於類別內部
protected不適用僅限於類別及其子類別
internal僅限於相同模組內僅限於相同模組內

Reference#

https://kotlinlang.org/docs/visibility-modifiers.html