Kotlin 简明教程
Kotlin - Extensions
Kotlin扩展提供了一种通过类扩展新功能的能力,无需通过类实现继承概念或使用装饰器之类的设计模式。基本上,这些扩展在不扩展类的情况下向现有类添加一些功能。
Kotlin扩展允许为第三方库中的类编写新函数,而无需修改该类。扩展函数的优点在于,它们可以像原始类的操作一样以通常的方式调用,而这些新函数被称为 Extension Functions 。
同样,我们还可以为现有的Kotlin类定义 extension properties 。
Extension Function
Kotlin扩展函数是类的成员函数,在类外定义。创建的扩展函数在该类内作为常规函数使用。
Syntax
以下是定义 extension function 的语法。此处,扩展函数使用类名和方法名进行声明。
fun <class_name>.<method_name>(){
....
function body
}
Example
在函数扩展中,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
Extended Library Classes
Kotlin允许扩展标准库类和自定义类。例如,如果您需要一个专门用于标准Kotlin String类的函数,该函数会返回字符串中可用元音的数量,String类中尚未提供此类方法,但可以使用 extension function 完成此任务。
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
Companion Object Extensions
Kotlin提供了另一种机制来实现Java的静态功能。这可以通过在类中声明并用 companion 关键字标记的 companion object 来实现。使用此机制,我们可以在工厂方法中创建类的对象,之后我们只需使用类名的引用调用该方法。
在以下示例中,我们将创建一个“伴随对象”。
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中的静态,但是在实际时间中,我们正在创建对象作为同一类中的成员变量。这就是它也包含在扩展属性下并且还可以称为对象扩展的原因。您基本上是在扩展同一类的对象以使用某些成员函数。
Extension with Nullable Receiver
Kotlin允许使用可为空的类类型定义 Extension Functions 。可以在可为空的对象变量上调用这些扩展函数。
要为可为空的接收器定义扩展,我们只需要在扩展函数内添加一个用于可为空的接收器的检查即可,并返回适当的值。
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
Extension Properties
Kotlin允许以与我们定义扩展函数非常类似的方式定义 extension properties 。扩展属性也在类的外部定义。由于扩展实际上不会向类中插入成员,因此扩展属性没有后备字段的有效方法。这就是扩展属性不允许初始值的原因。
我们可以在属性上添加getter和setter,这些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