扩展函数
扩展函数表示即使在不修改某个类的源码的情况下,仍然可以打开该类,向该类添加新的函数。
扩展函数的语法结构为:
fun ClassName.methodName(param1:Int, param2:Int) {
//TODO
}
相当于定义一个普通的函数,定义扩展函数只需要在函数名前加上ClassName.这一语法结构,就表示将该函数添加到指定类当中了。
比如虽然String类有内置的函数可以统计得到字符串的长度,但也可以通过该方法构建扩展函数进行统计:
fun String.letterCount():Int {
var count = 0
for (char in this) {
if (char.isLetter()) {
count++
}
}
return count
}
fun main() {
println("Hello".letterCount())
}
比如上面的代码就构建了String类的扩展函数,以统计字符串中字符的个数。
这就意味着虽然是对于String这样的final类,用户仍然可以通过扩展函数来实现一些客制化的功能。
运算符重载
运算符重载使用的是operator关键字,只要在指定函数的前面加上operator关键字,就可以实现运算符重载。这里的指定函数是和运算符对应的,比如加法运算符就是plus方法,减法运算符就是minus方法。
class Money(val value:Int) {
operator fun plus(money: Money):Money {
val sum = value + money.value
return Money(sum)
}
operator fun plus(newValue: Int):Money {
val sum = value + newValue
return Money(sum)
}
}
fun main() {
println(Money(2).plus(Money(3)).plus(5).value)
println((Money(2) + Money(3) + 5).value)
}
比如上面的代码中,使用operator关键字修饰plus函数,然后在该运算符重载中进行value的相加,最后返回相加后的对象。同时还实现了运算符重载的多重重载,这里的使用逻辑大致和C++中的运算符重载类似。
同时上述的函数调用形式可以使用正常的函数调用形式,也可以直接使用运算符的形式,两者的作用是等价的,不过后者是Kotlin的语法糖形式,看起来更为简便。
而在Kotlin中,语法糖表达式和实际调用函数的对应关系为:
语法糖表达式 | 实际调用函数 |
a + b | a.plus(b) |
a - b | a.minus(b) |
a * b | a.times(b) |
a / b | a.div(b) |
a % b | a.rem(b) |
a++ | a.inc(b) |
a-- | a.dec(b) |
+a | a.unaryPlus(b) |
-a | a.unaryMinus(b) |
!a | a.not(b) |
a == b | a.equals(b) |
a > b | a.compareTo(b) |
a < b | a.compareTo(b) |
a >= b | a.compareTo(b) |
a <= b | a.compareTo(b) |
a..b | a.rangeTo(b) |
a[b] | a.get(b) |
a[b] = c | a.set(b, c) |
a in b | b.contains(a) |
只是最后的contains方法的调用关系和之前的函数是相反的。