Kotlin-扩展函数和运算符重载(第一行代码Kotlin学习笔记6)

1. 扩展函数

如果我们之前是Java使用者,那么很遗憾的是,Java一直以来都不支持这个非常有用的功能。那么扩展函数是什么呢?其实扩展函数就是说在不修改某个类源码的情况下,仍然可以向该类添加新的函数。
比如我们想要统计一个字符串中字母的数量,如果没有扩展函数,那么我们就要写一个Util类,然后写一个方法,来作统计,例如:

object StringUtil{
    fun lettersCount(str:String):Int{
        var count = 0;
        for (char in str){
            if(char.isLetter()){
                count++
            }
        }
        return count
    }
}

然后我们这样调用:

fun main() {
    val str = "alk3r34"
    val count = StringUtil.lettersCount(str)
    println("count = $count")
}
//count = 4

这种写法是Java中最标准的实现思维,但是有了扩展函数,我们就可以用一种更加面向对象的思维来实现这个功能,我们可以将lettersCount这个函数,添加到String类中。下面我们来看下扩展函数的语法结构:

fun ClassName.methodName(param1: Int, param2: Int): Int {
      return 0
}

相比于普通函数,我们只需要在函数名前面加一个ClassName.的语法结构就可以了,下面我们就来看下使用扩展函数,怎么去统计字符串中的数据:

fun String.lettersCount() : Int{
    var count = 0
    for (char in this){
        if(char.isLetter()){
            count++
        }
    }
    return count
}

此处我们将lettersCount定义为String的扩展函数,那么这个函数中就自动拥有了String这个实例的上下文,因此lettersCount函数就不再需要接收一个字符串参数了,只需要直接遍历this即可,因为现在this代表字符串本身。然后我们只需要直接使用字符串来调用lettersCount方法就可以了:

fun getStringLetterCount() {
    val count = "abce254*2as#".lettersCount()
    println("letters count = ${count}")
}

扩展函数是不是很有趣,我们可以对任意的类进行扩展,接下来我们看一个更加有趣的语法糖,就是运算符重载。

2. 运算符重载

熟悉Java的小伙伴们都知道函数的重载,但是在kotlin中,我们可以对运算符进行重载。这么做有什么好处呢,在Java中,对于“+”号运算符,我们只有在字符串或者数字之间使用才有意义,但是我们无法让两个Student对象相加变得有意义。但是如果我们使用运算符重载,就可以让两个Student对象相加变得有意义,好比我们可以定义两个Student对象相加就说是让每个学生所持有的数本数相加。
接下来,我们先看下运算符重载的基本语法:

//重载“+”号运算符
operator fun plus(obj: Obj): Obj {
            // 处理相加的逻辑
}

我们只需要在指定函数前面加上operator关键字即可,但需要注意的是,我们必须要知道这个指定函数是什么,因为不同的运算符对应的重载函数也是不同的,如“+”号对应的是plus(),"-"号对应的是minus()函数。接下来我们举例看下:

class Student(val name:String,val books:Int) {
    operator fun plus(stu:Student):Student{
        val sum = books + stu.books
        return Student("allbooks",sum)
    }
}
fun main() {
    val stu1 = Student("张三",5)
    val stu2 = Student("小明",3)
    val allBooks = stu1 + stu2
    println("allbooks = ${allBooks.books}")
}
//allbooks = 8

再比如,我们可以Money进行相加,同时我们还可以进行汇率的换算:

使用密封类定义币种
sealed class MoneyType{}
class RMB :MoneyType()
class Dollor:MoneyType()
//定义数据类Money
data class Money(val moneyType: MoneyType,val value:Int){
    operator fun plus(money: Money):Money{
        val sum = when(moneyType){
            is RMB -> {when(money.moneyType) {
                is RMB -> value + money.value
                is Dollor -> value + money.value*7
            }}
            is Dollor -> {when(money.moneyType) {
                is RMB -> value + money.value / 7
                is Dollor -> value
            }}
        }
        return Money(moneyType,sum)
    }
}
fun main() {
    val rmb = Money(RMB(),7)
    val dollor = Money(Dollor(),7)
    val dolorSum = dollor + rmb
    val rmbSum = rmb + dollor
    println("dolorSum = $dolorSum")
    println("rmbSum = $rmbSum")
}
//dolorSum = Money(moneyType=com.liuhp.helloworld.part5.Dollor@5e481248, value=8)
//rmbSum = Money(moneyType=com.liuhp.helloworld.part5.RMB@66d3c617, value=56)

关于数据类和密封类的相关知识,请移步:Kotlin-类与对象:data数据类,object单例类,sealed密封类(第一行代码Kotlin学习笔记2).
此段代码我们先判断了当前币种,然后以当前币种为基准进行换算。不熟悉when语句的同学,请移步:Kotlin-变量var,val,${}和函数when,for-in(第一行代码Kotlin学习笔记1).

运算符重载对照表(复制于第一行代码随书ppt)

复制于第一行代码随书ppt
我们上面只说了“+”号的重载函数puls(),其实我们可以用运算符重载实现很多好玩儿的功能。剩下的就请秀发茂密的童鞋们自行探索吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值