相信很多小伙伴对于密封类的概念有过了解,但是并不知道在什么具体的环境下使用它
1、密封类跟枚举有什么区别(枚举可以看我的这篇文章)
- 每个枚举常量仅作为单个实例存在,而密封类的子类可以具有多个实例,密封类可以说是枚举的扩展。
- 密封类的子类是确定的,除了已经定义好的子类外,不能再有其他子类
- 密封类的所有子类必须在同一文件中,可以不再同一个块中
- 所有需要使用when去判断的子类都需要继承密封类,否则没有语法判断,如下AAA就继承了(NETS类等也继承了),BUILD类就没有继承,因为BUILD是操作类,不需要有语法检查
2、为什么要使用密封类
- 有效的保护代码(普通类的父类需要用open来修饰才能继承,密封类不需要,可以有效的保护子类)
- 通过when,可以包含所有的情况,不存在else的情况,这样后续增加其他密封类的子类,不会出现疏忽遗漏存在
3、什么情况下使用密封类
- 当你想使用枚举的时候,又因为枚举只有单一的常量,而实现不了你想要的结果
//枚举
enum class ServerEnum(val key: String, val value: String) {
TEST("http://10.10","http://img.com/"),
VIDEO("http://10.11","http://video.com/");
}
如:在我的项目中用到的支付,有NETS支付,adyen支付,DBS支付,而每个支付又有不同的状态(支付中,待支付,已支付等),又有对类的操作(绑卡,支付等),在此中情况下,就可以使用密封类了
调用密封类
PaySealed.BUILD.toPay(NETS("123","456"))//绑卡
PaySealed.BUILD.bindCard(NETS("123","456"))//去支付
PaySealed.BUILD.unBindCard(NETS("123","456"))//解绑卡
PaySealed.StatuTypeEnum.SUCCESS.statuType//当前卡的状态枚举
密封类的内容
//各个支付需要的参数
data class NETS(var mid: String, var muid: String) : PaySealed()//NETS支付
data class ADYEN(var signRequestInfoBean: String) : PaySealed()//ADYEN支付
data class DBS(var txnrefId: String) : PaySealed()//DBS支付
sealed class PaySealed {
//支付的状态
enum class StatuTypeEnum(var statuType: String, var statuName: String) {
SUCCESS("succ", "支付成功"),//支付成功
FAIL("fail", "支付失败"),//支付失败
INIT("init", "实付中"),//实付中
}
//卡的操作类
object BUILD{
//去支付、重新支付
fun toPay(paySealed: PaySealed): Unit = when (paySealed) {
is NETS -> {
//NETS去支付方法
}
is ADYEN -> {
//ADYEN去支付方法
}
is DBS -> {
//DBS去支付方法
}
}
//绑卡
fun bindCard(paySealed: PaySealed): Unit = when (paySealed) {
is NETS -> {
//NETS绑卡
}
is ADYEN -> {
//ADYEN绑卡
}
is DBS -> {
//DBS绑卡
}
}
//注销卡
fun unBindCard(paySealed: PaySealed): Unit = when (paySealed) {
is NETS -> {
//NETS绑卡
}
is ADYEN -> {
//ADYEN绑卡
}
is DBS -> {
//DBS绑卡
}
}
}
}
#总结:
- 对于模块的操作可以使用密封类,比如音乐播放(快进、播放、暂停类等),视频播放,支付等
- 密封类的最大优点就是内部可以使用多种类(抽象,对象object,class,data class等),而且对于继承密封类的子类,在使用when的时候都可以有语法检查,防止后续需求修改时遗漏某个功能