美文网首页
每天学一点 Kotlin -- 对象进阶:操作符重载

每天学一点 Kotlin -- 对象进阶:操作符重载

作者: 冯可乐同学 | 来源:发表于2021-12-09 13:26 被阅读0次

    ----《第一季Kotlin崛起:次世代Android开发 》学习笔记

    总目录:每天学一点 Kotlin ---- 目录
    上一篇:每天学一点 Kotlin -- 对象进阶:类型别名
    下一篇:每天学一点 Kotlin -- 对象进阶:反射

    1. 操作符重载

    1.1 一个明显的例子:不是所有的类型的都可以进行加减乘除运算。比如自定义的 Person 类。

    1.2 如果想要对某些操作符提供新的功能,那就要进行操作符重载了。在章节:每天学一点 Kotlin -- 函数:操作符 中就已经学习过操作操作符的重载了。

    1.3 下面对各种类型操作符相应的函数名进行总结:
    (1) 一元操作符:(在这里,a 指代进行运算的类型)
    “+a” 的函数名是 “unaryPlus”,
    “-a” 的函数名是 “unaryMinus”,
    “!a” 的函数名是 “not”,
    “++” 的函数名是 “inc”,
    “--” 的函数名是 “dec”;

    (2) 二元操作符:(在这里,把 a 设为运算符左边的对象,b 设为运算符右边的对象)
    “a+b” 的函数名是 “plus”,
    “a-b” 的函数名是 “minus”,
    “a*b” 的函数名是 “times”,
    “a/b” 的函数名是 “div”,
    “a%b” 的函数名是 “rem”,
    “a..b” 的函数名是 “rangeTo”,
    “in” 也是一个操作符,“a in b”的函数名是 “contains”,“a !in b”的函数名还是“contains”;

    (3) 索引操作符:(在这里,a、b 表示对象,i、j 等其他字母表示索引)
    “a[i]” 的函数名是 “get(i)”,
    “a[i,j]” 的函数名是 “get(i,j)”,
    “a[i_1,...,i_n]” 的函数名是 “get(i_1,...,i_n)”,
    “a[i]=b” 的函数名是 “set(i,b)”,
    “a[i,j]=b” 的函数名是 “set(i,j,b)”,
    “a[i_1,...,i_n]=b” 的函数名是 “set(i_1,...i_n)”;

    (4) 调用操作符:小括号“()”就是调用操作符(在这里,a 指代对象,i、j 等其他字母指代参数)
    “a()” 的函数名是 “a.invoke()”,
    “a(i)” 的函数名是 “a.invoke(i)”,
    “a(i,j)” 的函数名是 “a.invoke(i,j)”,
    “a(i_1,...,i_n)” 的函数名是 “a.invoke(i_1,...,i_n)”;

    (5) 赋值类操作符:(在这里,a,b 指代对象)
    “a+=b” 的函数名是 “a.plusAssign(b)”,
    “a-=b” 的函数名是 “a.minusAssign(b)”,
    “a*=b” 的函数名是 “a.timesAssign(b)”,
    “a/=b” 的函数名是 “a.divAssign(b)”,
    “a%=b” 的函数名是 “a.modAssign(b)”,
    相等、不相等的操作符只要重写超类 Any 中的 equals() 方法就可以了,
    其他的四个比较操作符“>”“>=”“<”“<=”需要实现 Comparable 泛型接口。

    2. 举个栗子

    2.1 在章节:每天学一点 Kotlin -- 函数:操作符 的基础上,补充一些遗漏的例子

    2.2 重载一元操作符举例:

    class OperatePerson(name: String, age: Int) {
        val name = name
        val age = age
    }
    
    operator fun OperatePerson.unaryPlus() = OperatePerson(this.name, this.age + 1)
    
    fun testOperate1() {
        val p = OperatePerson("xiaoMing", 20)
        println((+p).age)
    }
    
    fun main() {
        testOperate1()
    }
    

    打印结果:

    21
    

    因为是重载,所以可以自定义操作符里面的逻辑,修改如下:

    operator fun OperatePerson.unaryPlus() = OperatePerson(this.name, this.age + 3)
    operator fun OperatePerson.unaryMinus() = OperatePerson(this.name, this.age - 3)
    
    fun testOperate1() {
        val p = OperatePerson("xiaoMing", 20)
        println((+p).age)
    
        val p1 = OperatePerson("xiaoMing", 20)
        println((-p1).age)
    }
    
    fun main() {
        testOperate1()
    }
    

    打印结果:

    23
    17
    

    2.3 重载二元操作符举例:
    见章节:每天学一点 Kotlin -- 函数:操作符 中的 2.5

    2.4 重载索引操作符举例:
    见章节:每天学一点 Kotlin -- 函数:操作符 中的 2.6.1

    2.5 重载调用操作符
    见章节:每天学一点 Kotlin -- 函数:操作符 中的 2.6.2

    2.6 重载赋值类操作符
    见章节:每天学一点 Kotlin -- 函数:操作符 中的 2.6.3,是直接重写了操作符 compareTo() 的方法。下面看一下实现 Comparable 泛型接口的实例。

    class OperatePerson1(name: String, age: Int) : Comparable<OperatePerson1> {
        val name = name
        val age = age
    
        override fun compareTo(other: OperatePerson1): Int {
            return if (this.age > other.age) {
                1
            } else if (this.age < other.age) {
                -1
            } else {
                0
            }
        }
    }
    
    fun testOperate2() {
        val p1 = OperatePerson1("xiaoMing", 20)
        val p2 = OperatePerson1("xiaoHong", 21)
    
        if (p1 > p2) {
            println("${p1.name}  年龄大于 ${p2.name}")
    
        } else if (p1 < p2) {
            println("${p1.name}  年龄小于于 ${p2.name}")
        } else {
            println("${p1.name}  年龄和 ${p2.name} 相等")
        }
    }
    
    fun main() {
        testOperate2()
    }
    

    打印结果:

    xiaoMing  年龄小于于 xiaoHong
    
    相关代码:https://gitee.com/fzq.com/test-demo

    相关文章

      网友评论

          本文标题:每天学一点 Kotlin -- 对象进阶:操作符重载

          本文链接:https://www.haomeiwen.com/subject/leytaltx.html