前言:每一个你不满意的将来,都有一个你没有努力的曾经。

一、概述

  密封类用于表示受限制的类层次结构,类中的值可以拥有受限集合中的一种类型,但不能拥有任何其他类型时。从某种意义上看,他们是枚举类的拓展:枚举类型的值集合也受到限制,但每个枚举常量仅作为单个实例存在,而一个密封类的子类可以有多个可以包含状态的实例。

通俗点来说,密封类是包含了一组受限的类集合,因为里面的类都是继承自这个密封类的。但是它和其他继承类(open)的区别在于密封类可以不被此文件外被继承,能有效保护代码。但是密封类的子类的扩展是可以在程序任何位置的。即可以不在同一文件下。

二、声明

2.1 基本声明

  要声明一个密封类,可以在类名之前加上 sealed 修饰符。一个密封类可以有子类,但是所有子类都必须在同一个文件中声明,作为密封类的本身。(kotlin 1.1之前,规则甚至更严格:类必须嵌套在密封类的声明中)

sealed class BaseSealed

定义的子类必须继承于密封类,表示一组受限的类。

sealed class BaseSealed {
        data class People(val name: String) : BaseSealed()

        object Student : BaseSealed()//单列模式
    }

上面实例使用了Kotlin 1.1 的另一个特性:数据类可以拓展其他类,包括封装类。

//执行
    var people1 = BaseSealed.People("Android")
    var people2 = BaseSealed.People("Kotlin")

    println("密封类:people1 == $people1 | people2 == $people2")

打印数据如下:

密封类:people1 == People(name=Android) | people2 == People(name=Kotlin)

密封的类本身是抽象的,它不能直接实例化,可以有抽象成员。

//var sealed = BaseSealed() //报错,密封类不能被实例化

密封类不允许有非私有构造函数(它们的构造函数默认是私有的)。

2.2 子类的类的拓展

注意:扩展密封类(间接继承)的子类的类可以放在任何地方,而不一定是在同一个文件中。

//SealedClassActivity.kt 文件中
    sealed class BaseSealed {
        data class People(val name: String) : BaseSealed()

        object Student : BaseSealed()//单列模式
    }

	//ScopeExtensions.kt 文件中
	//子类的类的拓展
	fun SealedClassActivity.BaseSealed.Student.share(name: String): String {
    	return name
	}

	//调用
	var name = BaseSealed.Student.share("Java")
    println("密封类子类拓展:name == $name")

打印数据如下:

密封类子类拓展:name == Java

2.3 密封类的好处

当你在 when 表达式中使用密封类时,使用密封类的主要好处就发挥了作用。如果可以验证语句是否涵盖所有情况,则不需要向语句中添加 else 子句。但是,只有当你使用 when 作为表达式(使用结果)而不是作为语句时,这个方法才有效。

sealed class BaseSealed {
        data class People(val name: String) : BaseSealed()

        object Student : BaseSealed()//单列模式
    }
    
	//when作为表达式
    private fun invite(base: BaseSealed) = when (base) {
        is BaseSealed.Student ->
            println("密封类when:BaseSealed.Student ")
        is BaseSealed.People ->
            println("密封类when:BaseSealed.People")
    }
    //覆盖所有情况,不需要添加else语句

	//执行
	invite(BaseSealed.Student)

打印数据如下:

密封类when:BaseSealed.Student

源码地址:https://github.com/FollowExcellence/KotlinDemo-master