【Kotlin】扩展函数作用域分析 ( 扩展函数导入 | 扩展函数重载 | 扩展函数作用域优先级 )
文章目錄
- I . 擴展函數 作用域 總結
- II . 擴展函數 作用域
- III . 擴展函數 作用域 簡單調用示例
- IV . 擴展函數 重載分析
- V . 擴展函數 重載代碼示例
- VI . 擴展函數 作用域 優先級 分析
- VII . 擴展函數 作用域 優先級 代碼示例分析
I . 擴展函數 作用域 總結
擴展函數作用域總結 :
① 擴展函數作用域 : 擴展函數使用需要導入包 , 如果在本包中使用 , 可以默認不導入包 ;
② 擴展函數可以重載 : 函數名相同 , 函數簽名不同的擴展函數可以同時定義 , 導入包時導入一次即可調用所有的重載的擴展函數 ;
③ 擴展函數作用域優先級 : 聲明導入的擴展函數優先級高于默認包的優先級 , 聲明導入哪個包就調用哪個包的擴展函數 ;
II . 擴展函數 作用域
1 . 擴展函數作用域 : 定義一個擴展函數 , 默認只能在本包中調用 , 如果在別的包調用擴展函數 , 需要導入擴展函數 ;
2 . 擴展函數導入 : 調用接收者類型的擴展函數 , 需要導入擴展函數的包 , 導入格式為 :
import 包名.擴展函數名3 . 調用定義在本包里的擴展函數 : 可以直接調用 , 導入擴展函數的操作可以省略 , 寫上也不會出錯 ;
4 . 調用定義在其它包的擴展函數 : 必須導入擴展函數 , 才能調用該擴展函數 ;
III . 擴展函數 作用域 簡單調用示例
1 . 分別在 本包 和 外包 中定義擴展函數 :
① 本包定義擴展函數 : 普通的擴展函數定義 , 在 extendbean 包的文件下定義 Student 類 , 在 extendbean 包的文件下定義 Student 類的擴展函數 ;
package extendbeanclass Student {var name : String = "Tom"var age : Int = 18 }//在同一個文件中擴展 fun Student.printName(){println("${this.name}") }② 外包定義擴展函數 : 外包中定義 Student 類的擴展函數 , 自然需要導入 Student 類 ;
package extenddeclareimport extendbean.Student//定義擴展函數 fun Student.printNameAndAge(){println("${this.name} , ${this.age}") }2 . 本包 中調用擴展函數 :
① 代碼分析 : 在 extendbean 包中調用 extenddeclare 包中的為 Student 擴展的 printNameAndAge 函數 , 需要使用 import extenddeclare.printNameAndAge 導入該擴展函數 ;
package extendbean//本包中可以不同導入 Student 包 //import extendbean.Student//在本包內定義的擴展函數就不需要導入包了 //import extendbean.printAge //import extendbean.printName//使用 Student 的擴展 , 也需要導入 擴展函數所在包名.擴展函數名 import extenddeclare.printNameAndAgefun main() {var student : Student = Student()student.printNameAndAge()student.printName() }② 執行結果 :
Tom , 18 Tom3 . 外包 中調用擴展函數 :
① 代碼分析 : 在 extendusage 包中調用 extendbean 包中的 Student 類 和 擴展函數 , 以及 extenddeclare 包中定義的 printNameAndAge 擴展函數 , 需要將 Student 類以及所有的擴展函數都聲明導入 , 才可以使用 ;
package extendusage//使用到 Student 需要導入該類的包 import extendbean.Student//使用 Student 的擴展 , 也需要導入 擴展函數所在包名.擴展函數名 import extendbean.printName import extenddeclare.printNameAndAgefun main() {var student : Student = Student()student.printNameAndAge()student.printName() }② 執行結果 :
Tom , 18 TomIV . 擴展函數 重載分析
1 . 包內禁止定義相同函數簽名的擴展函數 : 在同一個包里 , 定義了一個擴展函數后 , 不允許定義相同函數簽名的擴展函數 ; 不管是定義在同一個文件中 , 還是不同的文件中 , 函數簽名不可以重復 ;
2 . 原理分析 : 因為擴展函數是根據 包名.擴展函數名 識別的 , 如果在同一個包內定義了相同函數簽名的擴展函數 , 無法識別應該調用哪個擴展函數 ;
3 . 重載說明 : 擴展函數在同一個包內 , 可以進行重載操作 , 即定義函數名相同 , 參數列表和返回值類型或順序不同的函數 , 兩個同名函數簽名不同 , 因此可以區分調用 ;
V . 擴展函數 重載代碼示例
1 . 重載擴展函數導入 : 對于重載的擴展函數 , 可以導入一次包即可通過函數簽名調用不同的擴展函數 ;
2 . 定義重載擴展函數 : 為 Student 擴展了兩個函數 , 分別是 printName() 和 printName(num : Int) , 這兩個函數簽名不同 , 可以定義 , 調用時根據不同的函數簽名分別調用 ;
package extendbeanclass Student {var name : String = "Tom"var age : Int = 18 }//在同一個文件中擴展 fun Student.printName(){println("${this.name}") }//測試重載的函數可以只聲明一次 fun Student.printName(num : Int){println("${this.name}") }3 . 調用重載擴展函數 : 根據不同的函數簽名調用不同的擴展函數 ;
package extendbeanfun main() {var student : Student = Student()student.printName()student.printName(10) }4 . 執行結果 :
Tom name : Tom , num : 10VI . 擴展函數 作用域 優先級 分析
本節討論的是在不同包定義的相同函數簽名的擴展函數調用問題
1 . 不同的包可以定義相同函數簽名的擴展函數 : 在不同的包內 , 可以定義相同函數簽名的擴展函數 , 調用時需要考慮各種情況 ; 其導入包的擴展函數優先級較高 , 沒有發現導入包 , 才會去默認的本包中查找是否有定義該簽名的擴展函數 ;
2 . 情況 一 : 在包內調用本包和外包的 相同簽名的 擴展函數 ;
① 導入的包優先級高 : 如果導入外包擴展函數 , 就會調用外包的擴展函數 ;
② 本包默認優先級較低 : 如果沒有導入 , 就會默認調用本包定義的的擴展函數 ;
3 . 情況 二 : 在一個包中調用 其它兩個包 的 相同簽名的 擴展函數 ;
① 調用優先級 : 導入哪個包 , 就調用哪個包的擴展函數 ;
② 重復導入 : 兩個包都導入會報錯 ;
VII . 擴展函數 作用域 優先級 代碼示例分析
1 . 不同包中定義相同函數簽名的擴展函數 : 為 Student 類在不同的包中定義相同函數簽名的擴展函數 ;
① 在 extendbean 包定義了 Student.printNameAndAge() 擴展函數 :
package extendbeanclass Student {var name : String = "Tom"var age : Int = 18 }//定義擴展函數 fun Student.printNameAndAge(){println("${this.name} , ${this.age}") }② 在 extenddeclare 包也定義了相同函數簽名的 Student.printNameAndAge() 擴展函數 :
package extenddeclareimport extendbean.Student//定義擴展函數 fun Student.printNameAndAge(){println("${this.name} , ${this.age}") }2 . 在 extendbean 包中調用擴展函數分析 :
① 沒有導入 extenddeclare.printNameAndAge 包 : 直接根據函數簽名調用擴展函數 , 此時調用的是本包中定義的擴展函數 ;
package extendbean//使用 Student 的擴展 , 也需要導入 擴展函數所在包名.擴展函數名 //import extenddeclare.printNameAndAge//此處注釋掉了導入包的操作fun main() {var student : Student = Student()student.printNameAndAge() }執行結果 : 根據結果可以看到 , 調用的是 extendbean 包中的擴展函數 ;
extendbean : Tom , 18② 導入了 extenddeclare.printNameAndAge 包 :
package extendbean//使用 Student 的擴展 , 也需要導入 擴展函數所在包名.擴展函數名 import extenddeclare.printNameAndAgefun main() {var student : Student = Student()student.printNameAndAge() }執行結果 : 根據結果可以看到 , 調用的是 extenddeclare 包中的擴展函數 ;
extenddeclare : Tom , 182 . 在 extendusage 包中調用擴展函數分析 : 這是個第三方包 , 分別在 extendbean 和 extenddeclare 定義了兩個相同函數簽名的 Student 擴展函數 ;
① 聲明哪個包就調用對應包的方法 : 此時聲明導入的是 extendbean.printNameAndAge , 就會調用 extendbean 包下的擴展函數 ;
package extendusage//使用到 Student 需要導入該類的包 import extendbean.Studentimport extendbean.printNameAndAge //import extenddeclare.printNameAndAgefun main() {var student : Student = Student()student.printNameAndAge() }執行結果 :
extendbean : Tom , 18② 如果都聲明報錯 : 如果兩個包都聲明 , 會如下錯誤 Overload resolution ambiguity. All these functions match. ;
總結
以上是生活随笔為你收集整理的【Kotlin】扩展函数作用域分析 ( 扩展函数导入 | 扩展函数重载 | 扩展函数作用域优先级 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Kotlin】扩展属性 ( 扩展变量属
- 下一篇: 【Kotlin】扩展接收者 与 分发接收