• Kotlin--Sealed Class Sealed Interface


    Sealed class

    1 其子类可以出现在定义 sealed class 的不同文件中,但不允许出现在与不同的 module 中,且需要保证 package 一致

    2 sealed class 是抽象类,可以拥有抽象方法,无法直接实例化。

    3 sealed class 的实例,可配合 when 表达式进行判断,当所有类型覆盖后可以省略 else 分支。如果没有覆盖所有类型,也没有 else 统筹则会发生编译警告或错误

    4 当 sealed class 没有指定构造方法或定义任意属性的时候,建议子类定义成单例,因为即便实例化成多个实例,互相之间没有状态的区别
    5 子类,包括普通 class、data class、object、sealed class 等

     sealed class GameAction(times: Int) {
         object Start : GameAction(1)
         data class AutoTick(val time: Int) : GameAction(2)
         class Exit : GameAction(3)
     }
     object Restart : GameAction(4)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    判断 sealed class 内部子类类型自然需要指定父类前缀
    object class 的话可以直接进行实例判断,也可以用 is 关键字判断类型匹配
    普通 class 类型的话则必须加上 is 关键字
    判断 sealed class 外部子类类型自然无需指定前缀

     class TestSealed {
         fun test(gameAction: GameAction) {
             when (gameAction) {
                 GameAction.Start -> {}
                 // is GameAction.Start -> {}
                 is GameAction.AutoTick -> {}
                 is GameAction.Exit -> {}
                 
                 Restart -> {}
             }
         }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    Sealed Interface

     enum class Action {
         Tick,
         // GameAction
         Start, Exit, Restart,
         // BirdAction
         Up, Down, HitGround, HitPipe, CrossedPipe,
         // PipeAction
         Move, Reset,
         // RoadAction
         // 防止和 Pipe 的 Action 重名导致编译出错,
         // 将功能差不多的 Road 移动和重置 Action 定义加上了前缀
         RoadMove, RoadReset
     }
     
     fun dispatch(action: Action) {
         when (action) {
             Action.Tick -> TODO()
     
             Action.Start -> TODO()
             Action.Exit -> TODO()
             Action.Restart -> TODO()
     
             Action.Up -> TODO()
             Action.Down -> TODO()
             Action.HitGround -> TODO()
             Action.HitPipe -> TODO()
             Action.CrossedPipe -> TODO()
     
             Action.Move -> TODO()
             Action.Reset -> TODO()
     
             Action.RoadMove -> TODO()
             Action.RoadReset -> TODO()
         }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    借助 sealed interface 我们可以给抽出 interface,并将 enum 进行层级拆分。更加清晰、亦不用担心重名

     sealed interface Action
     
     enum class GameAction : Action {
         Start, Exit, Restart
     }
     
     enum class BirdAction : Action {
         Up, Down, HitGround, HitPipe, CrossedPipe
     }
     
     enum class PipeAction : Action {
         Move, Reset
     }
     
     enum class RoadAction : Action {
         Move, Reset
     }
     
     object Tick: Action
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    使用的时候就可以对抽成的 Action 进行嵌套判断:

     fun dispatch(action: Action) {
         when (action) {
             Tick -> TODO()
    
             is GameAction -> {
                 when (action) {
                     GameAction.Start -> TODO()
                     GameAction.Exit -> TODO()
                     GameAction.Restart -> TODO()
                 }
             }
             is BirdAction -> {
                 when (action) {
                     BirdAction.Up -> TODO()
                     BirdAction.Down -> TODO()
                     else -> TODO()
                 }
             }
             is PipeAction -> {
                 when (action) {
                     PipeAction.Move -> TODO()
                     PipeAction.Reset -> TODO()
                 }
             }
             is RoadAction -> {
                 when (action) {
                     RoadAction.Move -> TODO()
                     RoadAction.Reset -> TODO()
                 }
             }
         }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
  • 相关阅读:
    递归讲解-分形树(python版:两种书写方法)
    2331. 计算布尔二叉树的值
    xss盲打
    TikTok国际版 使用特网科技Bluestacks模拟器安装方法
    惊爆GitHub!腾讯T14级SQL首席专家开源分布式数据库架构实践手册
    浅入浅出 1.7和1.8的 HashMap
    Linux22 --- 网络为什么要分层、使用tcp协议实现两个进程间通信的功能、IP地址转换函数
    面向对象编程-正则表达式
    漫谈测试成长之探索——测试汇报
    【GAMES101 作业3】渲染小奶牛+使用.obj模型+双线性插值+踩坑总结
  • 原文地址:https://blog.csdn.net/u014105655/article/details/127861124