Kotlin - 擴充套件



Kotlin 擴充套件提供了無需透過類實現繼承概念或使用裝飾器等設計模式即可為類新增新功能的能力。這些擴充套件基本上是在現有類中新增一些功能,而無需擴充套件類。

Kotlin 擴充套件允許為來自第三方庫的類編寫新函式,而無需修改該類。擴充套件函式的優點是它們可以像原始類的方法一樣以通常的方式呼叫,這些新函式被稱為**擴充套件函式**。

類似地,我們還可以為現有的 Kotlin 類定義**擴充套件屬性**。

擴充套件函式

Kotlin 擴充套件函式是類的成員函式,它是在類外部定義的。建立的擴充套件函式在該類內部用作常規函式。

語法

以下是定義**擴充套件函式**的語法。這裡,擴充套件函式是使用類名和方法名宣告的。

fun <class_name>.<method_name>(){
 ....
 function body
}

示例

在函式擴充套件中,Kotlin 允許在主類之外定義方法。在下面的示例中,我們將看到擴充套件如何在函式級別實現。

class Alien {
   var skills : String = "null"
	
   fun printMySkills() {
      print(skills)
   }		
}
fun main(args: Array<String>) {
   var  a1 = Alien()
   a1.skills = "JAVA"
   //a1.printMySkills()
	
   var  a2 = Alien()
   a2.skills = "SQL"
   //a2.printMySkills()
	
   var  a3 = Alien()
   a3.skills = a1.addMySkills(a2)
   a3.printMySkills()
}
fun Alien.addMySkills(a:Alien):String{
   var a4 = Alien()
   a4.skills = this.skills + " " +a.skills
   return a4.skills
}

在上面的示例中,“Alien”類中沒有任何名為“addMySkills()”的方法,但是,我們仍然在類外部的其他地方實現了相同的方法,這就是擴充套件的魔力。

執行上面的 Kotlin 程式後,將生成以下輸出

JAVA SQL

擴充套件庫類

Kotlin 允許擴充套件標準庫類以及使用者定義的類。例如,如果您需要一個用於標準 Kotlin String 類的專用函式,該函式將返回字串中母音的數量,則 String 類中尚不存在此類方法,但您可以使用**擴充套件函式**來完成此任務。

fun main(args: Array<String>) {
   val str = "Good morning Kotlin"
   
   val result = str.countVowels()
   println("Number of vowels: $result")
}
fun String.countVowels(): Int{
   var vowels = 0
   for (i in 0.. this.length - 1) {
      val ch = this[i]
      if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') {
         ++vowels
      }
   }
   return vowels; 
}

執行上面的 Kotlin 程式後,將生成以下輸出

Number of vowels: 6

伴生物件擴充套件

Kotlin 提供了另一種實現 Java 靜態功能的機制。這可以使用在類內部宣告並用**companion**關鍵字標記的**伴生物件**來實現。使用這種機制,我們可以在工廠方法內部建立一個類的物件,然後我們只需使用類名的引用來呼叫該方法。

在下面的示例中,我們將建立一個“伴生物件”。

fun main(args: Array<String>) {
   println("Heyyy!!!"+A.show())
}
class A {
   companion object {
      fun show():String {
         return("You are learning Kotlin from TutorialsPoint.com")
      }
   }
}

執行上面的 Kotlin 程式後,將生成以下輸出

Heyyy!!! You are learning Kotlin from TutorialsPoint.com

上面的示例看起來像 Java 中的靜態方法,但是,實際上我們正在建立一個作為同一類成員變數的物件。這就是為什麼它也包含在擴充套件屬性中,並且可以替代地稱為物件擴充套件的原因。您基本上是在擴充套件同一類的物件以使用一些成員函式。

可空接收器的擴充套件

Kotlin 允許定義具有可空類型別的**擴充套件函式**。這些擴充套件函式可以在可空物件變數上呼叫。

要為可空接收器定義擴充套件,我們只需要在擴充套件函式內部新增一個可空接收器檢查,並返回相應的值。

fun main(args: Array<String>) {
   var str1 = "Good morning Kotlin"
   var str2 : String? = null
   
   var result = str1.countVowels()
   println("Number of vowels in str1 : $result")
   
   result = str2.countVowels()
   println("Number of vowels in str2 : $result")
}
fun String?.countVowels(): Any{
   if (this == null) return "null"
   
   var vowels = 0
   for (i in 0.. this.length - 1) {
      val ch = this[i]
      if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') {
         ++vowels
      }
   }
   return vowels; 
}

執行上面的 Kotlin 程式後,將生成以下輸出

Number of vowels in str1 : 6
Number of vowels in str2 : null

擴充套件屬性

Kotlin 允許以與定義擴充套件函式非常相似的方式定義**擴充套件屬性**。擴充套件屬性也在類外部定義。由於擴充套件實際上並沒有將成員插入類中,因此擴充套件屬性沒有有效的支援欄位的方法。這就是為什麼擴充套件屬性不允許初始化程式的原因。

我們可以新增 getter 和 setter 以及屬性,它們只是擴充套件函式。

class Temperature(var celsius: Float)

fun main(args: Array<String>) {
   val t = Temperature(40f)
   println(t.fahrenheit)

   t.fahrenheit = 85f
   println(t.celsius)
}
var Temperature.fahrenheit: Float
    get() = (celsius * 9 / 5) + 32
    set(value) {
        celsius = (value - 32) * 5 / 9
    }

執行上面的 Kotlin 程式後,將生成以下輸出

104.0
29.444445

測驗時間 (面試和考試準備)

答案:A

解釋

Kotlin 擴充套件函式在類外部定義,不會影響現有功能。

答案:D

解釋

所有關於擴充套件屬性的陳述都是正確的。

廣告