如果要在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有什么特性吧!

首先,先创建一个名为Operationsealed 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,分別是AddSubtractMultiplyDivide,而且

也只能有这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密封类相关推荐

  1. sealed密封类的使用

    sealed 密封类,为了避免滥用继承 形式: public sealed class myClass2 密封类不能作为基类被别的元素继承,但其可以继承别的类或接口 密封类中不能声明受保护成员或虚成员 ...

  2. 【Kotlin】Kotlin Sealed 密封类 ( 密封类声明 | 密封类子类定义 | 密封类特点 | 代码示例 )

    文章目录 I . 密封类概念 II . 密封类声明 III. 密封类注意事项 IV . 密封类 示例代码 I . 密封类概念 1 . 密封类作用 : 定义一个密封类 , 该类只能有有限个指定的子类 , ...

  3. kotlin学习之密封类(五)

    密封类的意义 比如,不用密封类 interface FatherClass class SonClass1: FatherClass{}class SonClass2: FatherClass{}fu ...

  4. Kotlin - 枚举与密封类

    枚举 Kotlin 支持枚举,需要使用 enum class 进行声明,如: enum class LogLevel {VERBOSE, DEBUG, INFO, WARN, ERROR, ASSER ...

  5. 理解Kotlin密封类Sealed

    " 密封类和接口表示受限制的类层次结构,提供对继承的更多控制.密封类的所有直接子类在编译时都是已知的.在定义密封类的模块和包之外不能出现其他子类.例如,第三方客户端不能在其代码中扩展您的密封 ...

  6. kotlin密封类_Kotlin密封级

    kotlin密封类 In this tutorial, we'll be looking into Kotlin Sealed Class. What are they? What's their u ...

  7. kotlin_基础_密封类(sealed)

    原文链接:https://blog.csdn.net/weixin_41953808/article/details/112499887 Kotlin密封类:sealed 密封类:用来定义受限的类继承 ...

  8. Kotlin 特色之 Sealed Class 和 Interface

    /   今日科技快讯   / 近日,我国在太原卫星发射中心使用长征六号改运载火箭,成功将云海三号卫星发射升空,卫星顺利进入预定轨道,发射任务获得圆满成功.该卫星主要用于开展大气海洋环境要素探测.空间环 ...

  9. Kotlin 密封类代替枚举类

    密封类代替枚举类 在Kotlin中由于密封类的特性,所以可以完全取代枚举类 应为object是final类,所以不能继承普通类,但是密封类是abstract,所以可以继承 示例中使用了中缀符号infi ...

最新文章

  1. DNNBrain:北师大团队出品,国内首款用于映射深层神经网络到大脑的统一工具箱...
  2. HDU 5298 Solid Geometry Homework 暴力
  3. 二十年编程语言风云,哪款是你的爱豆?
  4. 安装mariadb以及允许远程访问
  5. CABasicAnimation动画
  6. Asianux将成为最先进的安全Linux操作系统
  7. vim正则表示式替换
  8. 「报表开发者必看」避开这6个误区,报表才能好看又实用
  9. 台式电脑计算机图标打不开怎么办,电脑计算机图标打不开怎么办
  10. pmp第六版错题集6.1
  11. uniapp开发App如何引入阿里巴巴矢量库图标
  12. DIY01_NE555叮咚门铃
  13. android wps mac 下载地址,wps for mac下载
  14. 无法听到计算机发出的声音怎么办,为什么视频对方听不到我说话_电脑视频对方听不到声音的解决方法...
  15. java监控命令_Java程序各种监控命令和排查方法
  16. v.douyin.com/xxx v.ixigua.com/xxx抖音西瓜网址官方生成制作抖音西瓜缩短口令网址(仅供参考学习)
  17. 【Python】基于机器学习的财务数据分析——识别财务造假
  18. 离群值是什么意思_离群值!离群值?离群值!
  19. Qt——用在ARM板上的Mplayer(1.3.0,1.0rc4)安装编译步骤!还有,Mplayer背景抖动闪烁问题解答,终于来了!
  20. Codeforces 743 D Chloe and pleasant prizes

热门文章

  1. linux 跨平台查询 lxr,利用LXR来生成Linux内核代码的交叉索引页面
  2. Java selenium 爬取 星图
  3. python范例_最佳Python代码范例
  4. Spark数据倾斜解决
  5. java模拟魔兽世界武器掉落
  6. 药店管理系统|数据库设计
  7. iOS开发-简单图片背景替换 实现抠图效果
  8. Keep熬过冬天,但互联网健身的生意依然不好做
  9. ESP8266连接中国移动ONENET物联网平台TCP透传实现WIFI远程控制
  10. 扫码签到突破100000用户