Kotlin - 密封类、密封接口 sealed

一、概念 

  • 用来表示受限的类继承结构:当一个值为有限的几种类型,而不能有任何其它类型时。
  • 由于编译器知道一共有几种类型,可用来优化 when 对分支的判断:
    • 后期新增类型,却忘记修改 when 分支,最后走了 else 默认情况。(译器会提醒未穷举不给通过)。
    • 很明确只存在几种情况,却为了满足编译器的要求写无效分支。(不必再写 else 默认分支)。
  • 声明一个密封类使用 sealed 关键字,它是抽象类,造函数默认是 protected 可指定为 private。
  • 当子类没有指定构造和属性时应该定义成 object,因为即便创建多个实例相互之间没有状态区别,编译器会提示 “ sealed' subclass has no state and no overridden 'equals() ”。在 Kotlin v1.9 版本新增了 data object 用于取代 object 的用法,编译器会提示“'sealed' sub-object can be converted to 'data object' ”,toString() 不会打印 HashCode 等无用信息让输出更有意义。
sealed class Language {
    //定义在同一类中
    data object English : Language()
    data class French(val str: String) : Language()
    class German(str: String) : Language()
}

//定义在同一文件中
data object Chinese : Language()
data class Japanese(val str: String) : Language()
class Korean(str: String) : Language()

fun demo(language: Language) {
    when (language) {
        //单例唯一直接判断实例,定义在类中需要指定外部类
        Language.English -> TODO()
        is Language.French -> TODO()
        is Language.German -> TODO()
        Chinese -> TODO()
        is Japanese -> TODO()
        is Korean -> TODO()
    }
}

二、与枚举类的区别

enum只是一个值(常量),seald可以是一个值(定义成 data object 不携带数据),还可以是一个有状态的值(定义成 data class 携带数据)。

enum 更在意类型

seald 更在意数据
创建实例每个常量都是单例,是枚举类的实例子类可以有多个自己的实例
构造传参常量形参跟enum一样子类构造可以有参可以无参
属性子类可以有各自的成员属性实现更多功能
函数只能重写枚举类的函数可以自定义函数

三、版本说明

Kotlin v1.0:直接子类必须是密封类的内部类。

Kotlin v1.1:直接子类必须跟密封类在同一文件中,间接子类可以在不同文件中。

Kotlin v1.5:直接子类必须跟父类在同一个 Gradle Module 且同一包名下(避免文件过大并限制类的扩展)。增加了密封接口。

四、密封接口

继承起来,接口比类更灵活,又有助于实现多类型层级嵌套。

语言中文普通话
上海话
四川话
英文美国
印度
新加坡

4.1 密封接口 + 密封接口

sealed interface Language

sealed interface Chinese : Language
object PuTongHua : Chinese
object ShangHaiHua : Chinese
object SiChuanHua : Chinese

sealed interface English : Language
object America : English
object India : English
object Singapore : English

//使用
fun demo(language: Language) {
    when (language) {
        is Chinese -> {
            when (language) {
                PuTongHua -> TODO()
                ShangHaiHua -> TODO()
                SiChuanHua -> TODO()
            }

        }
        is English -> {
            when (language) {
                America -> TODO()
                India -> TODO()
                Singapore -> TODO()
            }
        }
    }
}

4.2 密封接口 + 枚举类

sealed interface Language

enum class Chinese : Language{
    PuTongHua, ShangHaiHua, SiChuanHua
}

enum class English : Language{
    America, India, Singapore
}

fun demo(language: Language) {
    when (language) {
        is Chinese -> {
            when (language) {
                Chinese.PuTongHua -> TODO()
                Chinese.ShangHaiHua -> TODO()
                Chinese.SiChuanHua -> TODO()
            }

        }
        is English -> {
            when (language) {
                English.America -> TODO()
                English.India -> TODO()
                English.Singapore -> TODO()
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值