Kotlin:关于Sealed密封类
如果要在Java中列举,我们可能会用Enum,而在Kotlin中,除了Enum以外,还有一個更加强大的工具——Sealed Class。
Enum Class
在Kotlin中的枚举类可以写成:
enum class Size {S, M, L, XL
}
然后使用when
來判断:
fun getLength(size: Size): Int {when (size) {Size.S -> return 10Size.M -> return 30Size.L -> return 50Size.XL -> return 100}
}
枚举类也可以自带参数:
enum class Color(val rgb: String) {RED("0xFF0000"),GREEN("0x00FF00"),BLUE("0x0000FF")
}
使用看看:
fun main(args: Array<String>) {val length = getLength(Size.XL)println("length=$length")// 100val hex = Color.RED.rgbprintln("hex=$hex")// 0xFF0000for (v in Size.values()){println(v)}// S// M// L// XL
}
大guy~94醬。
Sealed Class:Enum Class 2.0
來看看Sealed Class有什么特性吧!
首先,先创建一个名为Operation
的sealed class
,加上execute()
方法,來玩玩看:
sealed class Operation {class Add(val value: Int) : Operation()class Subtract(val value: Int) : Operation()class Multiply(val value: Int) : Operation()class Divide(val value: Int) : Operation()
}fun execute(x: Int, op: Operation) = when (op) {is Operation.Add -> x + op.valueis Operation.Subtract -> x - op.valueis Operation.Multiply -> x * op.valueis Operation.Divide -> x / op.value
}fun main(args: Array<String>) {val result = execute(5, Operation.Subtract(3))println("result=$result")// result=2}
sealed class
是个很酷的class,以上面的代码为例:·类别中有4个class,分別是Add
、Subtract
、Multiply
与Divide
,而且
也只能有这4个class。什么意思呢?
让我们用execute()
方法来测试看看Operation
类别所有的枚举情況:
fun execute(x: Int, op: Operation) = when (op) {is Operation.Add -> x + op.valueis Operation.Subtract -> x - op.valueis Operation.Multiply -> x * op.valueis Operation.Divide -> x / op.value
}
如果我们试图将其中一种枚举情況刪除:
fun execute(x: Int, op: Operation) = when (op) {is Operation.Add -> x + op.valueis Operation.Subtract -> x - op.valueis Operation.Multiply -> x * op.value// delete this line
}
Compiler就会有森77的fu:
‘when’ expression must be exhaustive, add necessary ‘is Divide’ branch or ‘else’ branch instead
翻译:when表达式应该是全面性的,应该要包含「其它」情況
所以我们加入else
代表其他未过滤的枚举情況,就可以解決这个警告:
fun execute(x: Int, op: Operation) = when (op) {is Operation.Add -> x + op.valueis Operation.Subtract -> x - op.valueis Operation.Multiply -> x * op.valueelse -> x
}
也就是说,你可以在Sealed Class中定义所有可能的情況,而在搭配when
的使用下,compiler会强迫我们得去注意到这些情況是否都有被处理到,是个非常贴心的设计。
想像一下今天我們要开个API给別人,他可能不会知道一个参数status
的所有种类,但通过Sealed Class与when
的组合,可以强迫这个API的使用者去了解所有的种类,并进行处理。
基本上一個Sealed Class的Subclass预设不带任何参数,它会是个object:
sealed class Operation {class Add(val value: Int) : Operation()class Subtract(val value: Int) : Operation()class Multiply(val value: Int) : Operation()class Divide(val value: Int) : Operation()object Increment : Operation()object Decrement : Operation()
}fun execute(x: Int, op: Operation) = when (op) {is Operation.Add -> x + op.valueis Operation.Subtract -> x - op.valueis Operation.Multiply -> x * op.valueis Operation.Divide -> x / op.valueis Operation.Increment -> x + 1is Operation.Decrement -> x - 1
}fun main(args: Array<String>) {val result = execute(5, Operation.Increment)println("result=$result")// result=6}
注意到了吗?当搭配when做使用的時候,参数的Sealed Class subclass需要使用is判断
,不带参数的Object
不需要使用is判断
:
fun execute(x: Int, op: Operation) = when (op) {is Operation.Add -> x + op.valueis Operation.Subtract -> x - op.valueis Operation.Multiply -> x * op.valueis Operation.Divide -> x / op.valueOperation.Increment -> x + 1Operation.Decrement -> x - 1
}
因为Kotlin中的Object
就是最简单的单例模式,每个相同名称的Object其实
都是一样的,也只会有这么一个。
Sealed class进阶应用
我们可以将要对View
進行操作的功能封裝為一個sealed class(這邊為UiOp
),並在裡面列舉出我們將會進行的動作:
sealed class UiOp {object Show: UiOp()object Hide: UiOp()class TranslateX(val px: Float): UiOp()class TranslateY(val px: Float): UiOp()
}fun execute(view: View, op: UiOp) = when (op) {UiOp.Show -> view.visibility = View.VISIBLEUiOp.Hide -> view.visibility = View.GONEis UiOp.TranslateX -> view.translationX = op.pxis UiOp.TranslateY -> view.translationY = op.px
}
覆寫「+」號運算符,提升程式碼的易讀性:
class Ui(val uiOps: List = emptyList()) {operator fun plus(uiOp: UiOp) = Ui(uiOps + uiOp)
}
看一下使用範例:
val ui = Ui() +UiOp.Show +UiOp.TranslateX(20f) +UiOp.TranslateY(40f) +UiOp.Hiderun(view, ui)
fun run(view: View, ui: Ui) {ui.uiOps.forEach { execute(view, it) }
}
可以看到我们的方法run()
就是对View
進行操作。
进行什么操作呢?这些操作已经用非常易读的方式建构在ui变数了,藉由适时的使用sealed class,可以方便地让我们进行同一个系列的所有相关操作。
参考文章:https://carterchen247.medium.com/kotlin使用心得-sealed-class-82eccf890ac0
Kotlin:关于Sealed密封类相关推荐
- sealed密封类的使用
sealed 密封类,为了避免滥用继承 形式: public sealed class myClass2 密封类不能作为基类被别的元素继承,但其可以继承别的类或接口 密封类中不能声明受保护成员或虚成员 ...
- 【Kotlin】Kotlin Sealed 密封类 ( 密封类声明 | 密封类子类定义 | 密封类特点 | 代码示例 )
文章目录 I . 密封类概念 II . 密封类声明 III. 密封类注意事项 IV . 密封类 示例代码 I . 密封类概念 1 . 密封类作用 : 定义一个密封类 , 该类只能有有限个指定的子类 , ...
- kotlin学习之密封类(五)
密封类的意义 比如,不用密封类 interface FatherClass class SonClass1: FatherClass{}class SonClass2: FatherClass{}fu ...
- Kotlin - 枚举与密封类
枚举 Kotlin 支持枚举,需要使用 enum class 进行声明,如: enum class LogLevel {VERBOSE, DEBUG, INFO, WARN, ERROR, ASSER ...
- 理解Kotlin密封类Sealed
" 密封类和接口表示受限制的类层次结构,提供对继承的更多控制.密封类的所有直接子类在编译时都是已知的.在定义密封类的模块和包之外不能出现其他子类.例如,第三方客户端不能在其代码中扩展您的密封 ...
- kotlin密封类_Kotlin密封级
kotlin密封类 In this tutorial, we'll be looking into Kotlin Sealed Class. What are they? What's their u ...
- kotlin_基础_密封类(sealed)
原文链接:https://blog.csdn.net/weixin_41953808/article/details/112499887 Kotlin密封类:sealed 密封类:用来定义受限的类继承 ...
- Kotlin 特色之 Sealed Class 和 Interface
/ 今日科技快讯 / 近日,我国在太原卫星发射中心使用长征六号改运载火箭,成功将云海三号卫星发射升空,卫星顺利进入预定轨道,发射任务获得圆满成功.该卫星主要用于开展大气海洋环境要素探测.空间环 ...
- Kotlin 密封类代替枚举类
密封类代替枚举类 在Kotlin中由于密封类的特性,所以可以完全取代枚举类 应为object是final类,所以不能继承普通类,但是密封类是abstract,所以可以继承 示例中使用了中缀符号infi ...
最新文章
- DNNBrain:北师大团队出品,国内首款用于映射深层神经网络到大脑的统一工具箱...
- HDU 5298 Solid Geometry Homework 暴力
- 二十年编程语言风云,哪款是你的爱豆?
- 安装mariadb以及允许远程访问
- CABasicAnimation动画
- Asianux将成为最先进的安全Linux操作系统
- vim正则表示式替换
- 「报表开发者必看」避开这6个误区,报表才能好看又实用
- 台式电脑计算机图标打不开怎么办,电脑计算机图标打不开怎么办
- pmp第六版错题集6.1
- uniapp开发App如何引入阿里巴巴矢量库图标
- DIY01_NE555叮咚门铃
- android wps mac 下载地址,wps for mac下载
- 无法听到计算机发出的声音怎么办,为什么视频对方听不到我说话_电脑视频对方听不到声音的解决方法...
- java监控命令_Java程序各种监控命令和排查方法
- v.douyin.com/xxx v.ixigua.com/xxx抖音西瓜网址官方生成制作抖音西瓜缩短口令网址(仅供参考学习)
- 【Python】基于机器学习的财务数据分析——识别财务造假
- 离群值是什么意思_离群值!离群值?离群值!
- Qt——用在ARM板上的Mplayer(1.3.0,1.0rc4)安装编译步骤!还有,Mplayer背景抖动闪烁问题解答,终于来了!
- Codeforces 743 D Chloe and pleasant prizes