携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第21天,点击查看活动详情
代码逻辑中,很多时候我们会需要分支语句,来根据数据的情况走不同的处理逻辑,而密封类就是在这种情况下,方便我们的使用,而重载运算符,也可以让我们简化代码
密封类
介绍
密封类是用来表示受限的类继承结构
即当类中的一个值只能是有限的几种类型,而不能是其他的任何类型,从使用角度来说,相当于是枚举类的扩展
PS: Java17也有了这个密封类
使用
假设我们有中情形,需要根据一个type的数值来进行不同的逻辑,如下代码:
fun getMsg(type: Int) :String{
return when(type) {
1 -> TODO()
2 -> TODO()
else -> TODO()
}
}
编译器一定会提示我们需要写上有个else,如下图所示
这个时候是不是有点繁琐了,于是我们想到的一种优化方法,就是使用枚举类
enum class MyType{
TYPE_1,TYPE_2
}
fun getMsg(type: MyType) :String{
return when(type) {
MyType.TYPE_1 -> TODO()
MyType.TYPE_2 -> TODO()
}
}
而且可以通过编译器,将所有的枚举都加到分支上去(快捷键按下Alt+Enter
即可),如下图所示
但是,这个情况也有些限制,就是枚举类用来判断类型,但是不能灵活地携带些数据,如果使用密封类,就是解决此问题
密封类的关键字为sealed class
,如下代码所示:
sealed class MyType
class Type1(val data:String):MyType()
class Type2(val errorCode:Int):MyType()
fun getMsg(type: MyType) :String{
return when(type) {
is Type1 -> TODO()
is Type2 -> TODO()
}
}
这里Type1和Type2类都可以携带自己的数据
当然,上面只是个简单的写法,MyType这个类也可以继承或实现其他接口,比如说在RecyclerView中定义个ItemViewType,用来创建不同的itemView的类型
重载运算符
Kotlin中提供了基础的运算符,但是只是针对基础的数据类型,如Int,Double等
如果我们想让两个对象可以相加的功能,这个时候可以使用重载运算符的功能来实现
介绍
首先,先介绍下什么是运算符,如以下代码:
val a = 2
val b = 3
val result =a + b
这里的+
就是运算符,实际上这里的a+b
等同a.plus(b)
这里相当于语法糖的意思,实际上+
是调用的plus()
方法
重载运算符的关键字为operator
,具体可重载的运算符如下表所示:
表达式 | 实际调用方法 |
---|---|
a * b | a.times(b) |
a / b | a.div(b) |
a % b | a.mod(b) |
a + b | a.plus(b) |
a - b | a.minus(b) |
a += b | a.plusAssign(b) |
a -= b | a.minusAssign(b) |
a *= b | a.timesAssign(b) |
a /= b | a.divAssign(b) |
a %= b | a.remAssign(b) |
a == b | a.equals(b) |
a != b | !a.equals(b) |
a in b | b.contains(a) |
a !in b | !b.contains(a) |
a > b | a.compareTo(b) > 0 |
a < b | a.compareTo(b) < 0 |
a >= b | a.compareTo(b) >= 0 |
a <= b | a.compareTo(b) <= 0 |
+a | a.unaryPlus() |
-a | a.unaryMinus() |
!a | a.not() |
++a,a++ | a.inc() |
--a, a-- | a.dec() |
a[i] | a.get(i) |
a[i, j] | a.get(i, j) |
a[i_1, ..., i_n] | a.get(i_1, ..., i_n) |
a[i] = b | a.set(i, b) |
a[i, j] = b | a.set(i, j, b) |
a[i_1, ..., i_n] = b | a.set(i_1, ..., i_n, b) |
可能罗列的不全,具体参考运算符重载 | Kotlin
下面我们以*
为例,重载运算符来实现一个逻辑
在类中重载运算符
我们有个这样的代码
fun main() {
val list = arrayListOf<Teacher>()
repeat(3) {
val student =Teacher("test")
list.add(student)
}
}
class Teacher(name:String)
上面的代码是循环3次,并创建了Teacher对象,并添加到List中,实际上我们可以重载运算符,对Teacher类改造一下:
class Teacher(name: String) {
operator fun times(n: Int): List<Teacher> {
val list = arrayListOf<Teacher>()
repeat(n){
val temp = copyBean(this)
list.add(temp)
}
return list
}
}
然后使用就变为下面:
fun main() {
val student = Teacher("test")
//相当于此代码
//val list= student.times(3)
val list = student * 3
}
注意:
实际上,重载运算符相当于重载运算符对应的方法而已
方法的参数类型和返回类型,根据需要定义即可,不一定需要那么死板
使用扩展来重载运算符
上面提高的示例就是在类中进行重载,我们也可以通过扩展来实现给某个类的运算符进行重载
我们还是以上面的Teacher为例
class Teacher(name: String)
//扩展给Teacher加上重载运算符
operator fun Teacher.times(n: Int): List<Teacher> {
val list = arrayListOf<Teacher>()
repeat(n) {
val temp = copyBean(this)
list.add(temp)
}
return list
}