美文网首页KotlinNetty
kotlin密封类sealed

kotlin密封类sealed

作者: KevinGarnett21 | 来源:发表于2023-04-12 23:04 被阅读0次

    一. 概念

    Kotlin 中的密封类(Sealed Class)是一种特殊的类,用于限制类的继承结构。密封类允许你定义一组相关的类,并且只允许这些类作为其子类存在。\color{Red} {这种限制可以在编译时检查,从而减少了程序出错的可能性。}

    语法如下:

    sealed class MyClass {
        // ...
    }
    

    密封类通常用于\color{Red} {代替枚举类}。密封类的\color{Red} {优点在于可以更灵活地定义子类,而枚举类的每个成员都是固定的}。密封类还可以帮助你\color{Red} {编写更加类型安全的代码}

    二. 应用场景

    密封类的主要应用场景是在需要表示有限数量的类型的情况下。当你知道一个类的所有可能的子类时,可以使用密封类来表示这些子类。

    例如,如果你有一个表示不同任务状态的密封类 TaskState,你可以编写一个 when 表达式来处理不同的状态:

    /**
     * 密封类: 任务的状态
     */
    sealed class SealedTaskState {
        // 空闲
        object EMPTY : SealedTaskState()
    
        // 执行中
        object RUNNING : SealedTaskState()
    
        // 暂停中
        object PAUSE : SealedTaskState()
    }
    
    // 单元测试
    @Test
    fun test(sealedTaskState: SealedTaskState) {
        when (sealedTaskState) {
            // SealedTaskState有3种状态
            // 下面的数据必须包含所有的SealedTaskState里的状态,不然编译器会报错
            
            is SealedTaskState.EMPTY -> {
                println("空闲")
            }
            is SealedTaskState.RUNNING -> {
                println("执行中")
            }
            is SealedTaskState.PAUSE -> {
                println("暂停")
            }
        }
    }
    

    上面的示例中,使用了密封类封装了任务的状态,when处理了SealedTaskState所有状态发生的情况。

    三. 和普通类的区别

    class SealedTest {
    
        // 密封类测试
        @Test
        fun testSealedShape(sealedShape: SealedShape) {
            when (sealedShape) {
                is SealedCircle -> println("circle area:${sealedShape.getArea()}")
                // 'when' expression must be exhaustive, add necessary 'is SealedRectangle' branch or 'else' branch instead
                // 直接编译报错,提示必须要SealedRectangle分支或者else分支
                // is SealedRectangle -> println("rectangle area : ${sealedShape.getArea()}")
            }
        }
    
        // 普通类测试
        @Test
        fun testNormalShape(normalShape: NormalShape) {
            when (normalShape) {
                is NormalCircle -> println("circle area:${normalShape.getArea()}")
                // 可能出现漏掉判断的情况,比如这里,我们把普通类矩形注释了,IDE也没有提示报错
                // 但是在密封类中,在编译期我们就能看到错误
                // is NormalRectangle -> println("rectangle area : ${normalShape.getArea()}")
            }
        }
    }
    
    /**
     * 普通类: 形状
     */
    abstract class NormalShape {
        // 计算面积
        abstract fun getArea(): Double
    }
    
    // 普通类: 圆形
    class NormalCircle(private val radius: Double) : NormalShape() {
        override fun getArea(): Double {
            return Math.PI * radius * radius
        }
    }
    
    // 普通类: 矩形
    class NormalRectangle(private val width: Double, private val height: Double) : NormalShape() {
        override fun getArea(): Double {
            return width * height
        }
    }
    
    
    
    /**
     * 密封类: 形状
     */
    sealed class SealedShape {
        // 计算面积
        abstract fun getArea(): Double
    }
    
    // 密封类: 圆形
    class SealedCircle(private val radius: Double) : SealedShape() {
        override fun getArea(): Double {
            return Math.PI * radius * radius
        }
    }
    
    // 密封列: 矩形
    class SealedRectangle(private val width: Double, private val height: Double) : SealedShape() {
        override fun getArea(): Double {
            return width * height
        }
    }
    

    首先,没有使用密封类NormalShape的情况下,如果我们添加了新的形状类型,例如梯形或正方形,那么我们必须修改 testSealedShape 函数,以处理这些新类型的形状。其次,如果我们在 when 表达式中遗漏了某种类型的形状,那么我们将无法在编译时或运行时捕获这个错误,这可能会导致程序在处理该类型的形状时出现异常。

    由于 SealedShape 是一个密封类,它的子类是有限的,编译器可以确保 when 表达式处理了所有可能的情况。如果我们添加了一个新的图形类型,我们需要添加一个新的密封子类,并实现 getArea() 方法。这个过程可以在编译时检测到错误,而不是在运行时才发现错误。这就是密封类的优势之一。

    四. 总结

    从上面的示例说明来看,密封类的优势可以总结为以下几点:

    1. 编译时检查:由于密封类的子类是有限的,因此编译器可以检查 when 表达式是否涵盖了所有可能的情况。这可以避免在运行时才发现未处理的情况,从而提高代码的可靠性和安全性。
    2. 类层次结构的扩展能力:通过添加新的密封子类,可以轻松地扩展现有的类层次结构,而无需修改现有的代码。这可以提高代码的可维护性和可扩展性。
    3. 更清晰的代码:密封类可以使代码更加清晰和易于理解。它可以帮助程序员更好地组织代码,从而使其更容易理解和修改。

    总的来说,密封类是一种非常有用的语言特性,可以提高代码的可靠性、可维护性和可扩展性。如果您需要处理有限数量的可能情况,并且希望在编译时检测到未处理的情况,那么密封类是一个很好的选择。

    相关文章

      网友评论

        本文标题:kotlin密封类sealed

        本文链接:https://www.haomeiwen.com/subject/sqtaddtx.html