Kotlin Sealed類


密封(Sealed)類是一個限制類層次結構的類。 可以在類名之前使用sealed關鍵字將類宣告為密封類。 它用於表示受限制的類層次結構。

當物件具有來自有限集的型別之一,但不能具有任何其他型別時,使用密封類。
密封類別建構函式在預設情況下是私有的,它也不能允許宣告為非私有。

密封類宣告

sealed class MyClass

密封類的子類必須在密封類的同一檔案中宣告。

sealed class Shape{
    class Circle(var radius: Float): Shape()
    class Square(var length: Int): Shape()
    class Rectangle(var length: Int, var breadth: Int): Shape()
    object NotAShape : Shape()
}

密封類通過僅在編譯時限制型別集來確保型別安全的重要性。

sealed class A{
    class B : A()
    {
        class E : A() //this works.  
    }
    class C : A()
    init {
        println("sealed class A")
    }
}

class D : A() // this works  
{
    class F: A() // 不起作用,因為密封類在另一個範圍內定義。
}

密封類隱式是一個無法範例化的抽象類。

sealed class MyClass
fun main(args: Array<String>)
{
    var myClass = MyClass() // 編譯器錯誤,密封型別無法範例化。
}

密封類和 when 的使用

密封類通常與表達時一起使用。 由於密封類的子類將自身型別作為一種情況。 因此,密封類中的when表示式涵蓋所有情況,從而避免使用else子句。

範例:

sealed class Shape{
    class Circle(var radius: Float): Shape()
    class Square(var length: Int): Shape()
    class Rectangle(var length: Int, var breadth: Int): Shape()
    //  object NotAShape : Shape()  
}

fun eval(e: Shape) =
    when (e) {
        is Shape.Circle ->println("Circle area is ${3.14*e.radius*e.radius}")
        is Shape.Square ->println("Square area is ${e.length*e.length}")
        is Shape.Rectangle ->println("Rectagle area is ${e.length*e.breadth}")
        //else -> "else case is not require as all case is covered above"  
        //  Shape.NotAShape ->Double.NaN  
    }
fun main(args: Array<String>) {

    var circle = Shape.Circle(5.0f)
    var square = Shape.Square(5)
    var rectangle = Shape.Rectangle(4,5)

    eval(circle)
    eval(square)
    eval(rectangle)
}  
`

執行上面範例程式碼,得到以下結果 -

Circle area is 78.5
Square area is 25
Rectagle area is 20