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

解释

所有关于扩展属性的陈述都是正确的。

广告