<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      kotlin類與對象——>擴展

      1,擴展概念(OC中早期就有此功能)

        Kotlin 能夠擴展一個類的新功能而無需繼承該類或者使用像裝飾者這樣的設計模式。這通過叫做 擴展 的特殊聲明完成。例如,你可以為一個你不能修改的、來自第三方庫中的類編寫一個新的函數。這個新 增的函數就像那個原始類本來就有的函數一樣,可以用普通的方法調用。這種機制稱為擴展函數此外,也有擴展屬性, 允許你為一個已經存在的類添加新的屬性

      2.擴展函數,聲明一個擴展函數,我們需要用一個 接收者類型 也就是被擴展的類型來作為他的前綴。下面代碼為 MutableList<Int> 添加一個 swap 函數:

      fun MutableList<Int>.swap(index1: Int, index2: Int) {
          val tmp = this[index1] // “this”對應該列表
          this[index1] = this[index2]
          this[index2] = tmp
      }
      
      //這個 this 關鍵字在擴展函數內部對應到接收者對象(傳過來的在點符號前的對象)現在,我們對任意 MutableList<Int> 調用該函數了:
      val list = mutableListOf(1, 2, 3)
      list.swap(0, 2) // “swap()”內部的“this”會保存“list”的值
      
      //當然,這個函數對任何 MutableList<T> 起作用,我們可以泛化它:
      //為了在接收者類型表達式中使用泛型,我們要在函數名前聲明泛型參數
      fun <T> MutableList<T>.swap(index1: Int, index2: Int) {
          val tmp = this[index1] // “this”對應該列表
          this[index1] = this[index2]
          this[index2] = tmp
      }

      3.擴展是靜態解析的

      擴展不能真正的修改他們所擴展的類。通過定義一個擴展,你并沒有在一個類中插入新成員,僅僅是可 以通過該類型的變量用點表達式去調用這個新函數。

      我們想強調的是擴展函數是靜態分發的,即他們不是根據接收者類型的虛方法。這意味著調用的擴展函 數是由函數調用所在的表達式的類型來決定的,而不是由表達式運行時求值結果決定的。例如

      open class Shape
      class Rectangle : Shape()
      
      fun Shape.getName() = "Shape"
      fun Rectangle.getName() = "Rectangle"
      fun printClassName(s: Shape) {
          println(s.getName())
      }
      printClassName(Rectangle())
      //這個例子會輸出 "Shape",因為調用的擴展函數只取決于參數 s 的聲明類型,該類型是 Shape 類
      
      
      //如果一個類定義有一個成員函數與一個擴展函數,而這兩個函數又有相同的接收者類型、相同的名字,并且都適用給定的參數,這種情況總是取成員函數。例如:
      class Example {
          fun printFunctionType() {
              println("Class method")
          }
      }
      
      fun Example.printFunctionType() {
          println("Extension function")
      }
      Example().printFunctionType()
      //這段代碼輸出“Class method”。
      
      //當然,擴展函數重載同樣名字但不同簽名成員函數也完全可以
      class Example {
          fun printFunctionType() {
              println("Class method")
          }
      }
      
      fun Example.printFunctionType(i: Int) {
          println("Extension function")
      }
      Example().printFunctionType(1)

      4.可空接收者

        注意可以為可空的接收者類型定義擴展。這樣的擴展可以在對象變量上調用,即使其值為 null,并且可 以在函數體內檢測 this == null ,這能讓你在沒有檢測 null 的時候調用 Kotlin 中的toString():檢測發生在擴展函數的內部。

      fun Any?.toString(): String {
          if (this == null) return "null"
      // 空檢測之后,“this”會自動轉換為非空類型,所以下面的 toString() 
      // 解析為 Any 類的成員函數
          return toString()
      }

      5.擴展屬性,與函數類似,Kotlin 支持擴展屬性

      val <T> List<T>.lastIndex: Int 
          get() = size - 1

        5.1 注意:由于擴展沒有實際的將成員插入類中,因此對擴展屬性來說幕后字段是無效的。這就是為什么擴 展屬性不能有初始化器。他們的行為只能由顯式提供的 getters/setters 定義

      val House.number = 1 // 錯誤:擴展屬性不能有初始化器

      6.伴生對象的擴展,如果一個類定義有一個伴生對象 ,你也可以為伴生對象定義擴展函數與屬性。就像伴生對象的常規成員 一樣,可以只使用類名作為限定符來調用伴生對象的擴展成員:

      class MyClass {
          companion object {} // 將被稱為 "Companion"
      }
      
      fun MyClass.Companion.printCompanion() {
          println("companion")
      }
      
      fun main() {
          MyClass.printCompanion()
      }

      7.擴展的作用域

      //大多數時候我們在頂層定義擴展?直接在包里
      package org.example.declarations
      fun List<String>.getLongestString() { /*......*/}

         7.1 要使用所定義包之外的一個擴展,我們需要在調用方導入它

      package org.example.usage
      import org.example.declarations.getLongestString
      
      fun main() {
          val list = listOf("red", "green", "blue")
          list.getLongestString ()
      }

      8.擴展聲明為成員

        8.1 在一個類內部你可以為另一個類聲明擴展。在這樣的擴展內部,有多個 隱式接收者——其中的對象成員 可以無需通過限定符訪問。擴展聲明所在的類的實例稱為 分發接收者,擴展方法調用所在的接收者類型 的實例稱為 擴展接收者。

      class Host(val hostname: String) {
          fun printHostname() {
              print(hostname)
          }
      }
      
      class Connection(val host: Host, val port: Int) {
          fun printPort() {
              print(port)
          }
      
          fun Host.printConnectionString() {
              printHostname() // 調用 Host.printHostname() print(":")
              printPort() // 調用 Connection.printPort()
          }
      
          fun connect() { /*......*/
              host.printConnectionString()
          }
      }
      
      fun main() {
          Connection(Host("kotl.in"), 443).connect()
          //Host("kotl.in").printConnectionString(443) // 錯誤,該擴展函數在 Connection 外不可用
      }

        8.2 對于分發接收者與擴展接收者的成員名字沖突的情況,擴展接收者優先。要引用分發接收者的成員你可 以使用 限定的 this 語法。

      class Connection {
          fun Host.getConnectionString() {
              toString() // 調用 Host.toString()
              this@Connection.toString() // 調用 Connection.toString() }
          }
      }

        8.3 聲明為成員的擴展可以聲明為 open 并在子類中覆蓋。這意味著這些函數的分發對于分發接收者類型 是虛擬的,但對于擴展接收者類型是靜態的

      open class Base {}
      class Derived : Base() {}
      open class BaseCaller {
          open fun Base.printFunctionInfo() {
              println("Base extension function in BaseCaller")
          }
      
          open fun Derived.printFunctionInfo() {
              println("Derived extension function in BaseCaller")
          }
      
          fun call(b: Base) {
              b.printFunctionInfo() // 調用擴展函數
          }
      }
      
      class DerivedCaller : BaseCaller() {
          override fun Base.printFunctionInfo() {
              println("Base extension function in DerivedCaller")
          }
      
          override fun Derived.printFunctionInfo() {
              println("Derived extension function in DerivedCaller")
          }
      }
      
      fun main() {
          BaseCaller().call(Base()) // “Base extension function in BaseCaller”
          DerivedCaller().call(Base()) // “Base extension function in DerivedCaller”——分發接收者虛擬解析
          DerivedCaller().call(Derived()) // “Base extension function in DerivedCaller”——擴展接收者靜態解析
      }

       

      9.關于可見行的說明

      擴展的可?性與相同作用域內聲明的其他實體的可?性相同。例如:
      — 在文件頂層聲明的擴展可以訪問同一文件中的其他 private 頂層聲明;
      — 如果擴展是在其接收者類型外部聲明的,那么該擴展不能訪問接收者的 private 成員

       

       

       

      posted @ 2020-06-22 15:18  王世楨  閱讀(364)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 日韩毛片在线视频x| 91超碰在线精品| 在线A级毛片无码免费真人| 扒开双腿疯狂进出爽爽爽| 免费视频欧美无人区码| 欧洲熟妇色xxxx欧美老妇免费 | 国产美女精品自在线拍免费| 国产亚洲欧洲av综合一区二区三区| 亚洲国产精品成人一区二区在线| 久久精品国产一区二区三区| 欧洲美熟女乱又伦免费视频| 国产精品男女爽免费视频| 宜都市| 亚洲国产成人自拍视频网| 国产老妇伦国产熟女老妇高清| 久久精品久久电影免费理论片| 亚洲一区二区三区在线播放无码 | 亚洲国产美女精品久久久| XXXXXHD亚洲日本HD| 国产片一区二区三区视频| 亚洲精品久综合蜜| 久久国产精品老人性| 中国china体内裑精亚洲日本| 人妻无码久久久久久久久久久| 国产狂喷潮在线观看| 一本一道av中文字幕无码| 国产成人高清亚洲综合| 377p日本欧洲亚洲大胆张筱雨| 亚洲精品综合网中文字幕| 国产精品久久久久9999高清| 亚洲国产综合性亚洲综合性| 欧美乱码伦视频免费| 亚洲区色欧美另类图片| 亚洲精品无码在线观看| 欧美成人精品一级在线观看| 性欧美三级在线观看| 连南| 国产成人无码免费视频在线| 午夜成人性爽爽免费视频| 国产麻豆剧果冻传媒一区| 国产91精品一区二区蜜臀|