本篇文章主要介绍以下几个知识点:
- 扩展函数
- 运载符重载
内容参考自第一行代码第3版
1. 扩展函数
扩展函数是指即使在不修改某个类的源码的情况下,仍然可以打开这个类,向该类添加新的函数。
考虑要实现一个统计字符串中字母的数量的功能,则可定义如下函数:
object StringUtil {
fun lettersCount(str: String): Int {
var count = 0
for (char in str) {
if (char.isLetter()) {
count++
}
}
return count
}
}
调用方式如下:
fun main() {
val str = "ABC123xyz!@#"
val count = StringUtil.lettersCount(str) // 统计字符串str中的字母数量
println(count)
}
上述写法是 Java 编程的标准实现思维,但有了扩展函数后,可以用一种更加面向对象的思维来实现这个功能。
定义扩展函数的语法结构如下:
// 定义扩展函数只需在函数名的前面加上一个 ClassName. 的语法结构,
// 就表示将该函数添加到指定类了
fun ClassName.methodName(param1: Int, param2: Int): Int {
return 0
}
接下来把 lettersCount()
函数添加到 String 类中,如下:
fun String.lettersCount(): Int {
var count = 0
for (char in this) {
if (char.isLetter()) {
count++
}
}
return count
}
调用方式如下:
fun main() {
val count = "ABC123xyz!@#".lettersCount()
println(count)
}
注:扩展函数可以定义在任何一个现有类中,但最好把它定义成顶层方法,这样可以让扩展函数拥有全局的访问域。
小结:扩展函数在多数情况下可以让 API 更加简洁、丰富,更加面向对象。Kotlin 自带的一些扩展函数如用于反转字符串的 reverse()
函数,用于对首字母大写的 capitalize()
函数等,使编码更加简便了。
2. 运载符重载
在 Kotlin 中,可以将如 + - * / % ++ --
等所有运算符或其他的关键字进行重载,从而扩展这些运算符和关键字的用法。
实现运算符重载只要在指定函数的前面加上 operator
关键字,不同的运算符对应的重载函数也不同:
接下来以加号运算符为例,实现两个对象相加的功能,其语法结构如下:
class Obj {
// 关键字 operator 和 函数名 plus 固定不变,接收的参数和函数返回值自行设定,
// 这里表示一个 Obj 对象与另一个 Obj 对象相加,返回一个新的 Obj 对象
operator fun plus(obj: Obj): Obj {
// 处理相加逻辑
}
}
// 调用方式
val obj1 = Obj()
val obj2 = Obj()
val obj3 = obj1 + obj2
下面实现两个 Money 对象相加,首先定义个 Money 类如下:
// value 表示金额
class Money(val value: Int)
接着使用运算符重载来实现让两个 Money 对象相加的功能:
class Money(val value: Int) {
operator fun plus(money: Money): Money {
val sum = value + money.value
return Money(sum)
}
}
调用结果如下:
fun main() {
val money1 = Money(20)
val money2 = Money(18)
val money3 = money1 + money2
println(money3.value) // 打印结果是:38
}
若要让 Money 对象可以直接和数字相加,则可修改如下(Kotlin 允许对同一个运算符进行多次重载):
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)
}
}
这样 Money 对象就可以和数字相加了:
fun main() {
val money1 = Money(20)
val money2 = money1 + 18
println(money2.value) // 打印结果是:38
}
上表中最后一个 a in b
语法糖表达式对应的实际调用函数是 b.contains(a)
,Kotlin 中的 String 类有对 contains()
函数进行重载,如判断 “Wonderful” 字符串中是否含有 “Won” 字符串时:
if("Wonderful".contains("Won")) { }
而借助重载的语法糖表达式,可这样写:
if("Won" in "Wonderful") { }
小结:运算符重载用得好的话,可以玩出很多花样。
本篇文章就介绍到这。