在本教程中,我们将深入研究 Kotlin 密封类。它们是什么?它们有什么用途?我们将在下面解决所有这些问题。
Kotlin 密封类
简单来说,顾名思义,密封类是密封或封闭的,因此受限制。密封类用于表示受限制的类层次结构,其中对象或值只能在类型中的一种之间具有值,从而固定了类型层次结构。密封类通常用于在您知道给定值仅在给定选项集合之间时使用。
实现 Kotlin 密封类
在 Kotlin 中,密封类是以下方式实现的。
sealed class A{
class B : A()
class C : A()
}
要指定密封类,您需要添加修饰符 sealed
。密封类不能被实例化。因此,它们隐式地是抽象的。以下方式是行不通的。
fun main(args: Array<String>)
{
var a = A() //compiler error. Class A cannot be instantiated.
}
密封类的构造函数默认为私有。密封类的所有子类必须在同一文件中声明。密封类在编译时通过限制类型集合来确保类型安全。
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() //This won't work. Since sealed class is defined in another scope.
}
使用構造函數創建封閉類。
sealed class A(var name: String){
class B : A("B")
class C : A("C")
}
class D : A("D")
fun main(args: Array<String>) {
var b = A.B()
var d = D()
}
fun main(args: Array<String>) {
val e = A.E("Anupam")
println(e) //prints E(name=Anupam)
var d = A.D
d.name() //prints Object D
}
sealed class A{
class B : A()
class C : A()
object D : A()
{
fun name()
{
println("Object D")
}
}
data class E(var name: String) : A()
}
枚舉和封閉類的區別
在 Kotlin 中,封閉類可以被稱為增強版的枚舉類。封閉類允許我們創建具有不同類型的實例,而不像 枚舉 那樣限制我們對所有枚舉常量使用相同類型。在枚舉類中無法實現以下功能。
enum class Months(string: String){
January("Jan"), February(2),
}
枚舉類僅允許所有常量使用單一類型。這就是封閉類通過允許多個實例來幫助我們的地方。
sealed class Months {
class January(var shortHand: String) : Months()
class February(var number: Int) : Months()
class March(var shortHand: String, var number: Int) : Months()
}
您如何在項目中使用封閉類的此功能?在類似新聞稿的應用程序中,您可以像下面所示為狀態、圖像、視頻帖子創建三種不同的類型。
sealed class Post
{
class Status(var text: String) : Post()
class Image(var url: String, var caption: String) : Post()
class Video(var url: String, var timeDuration: Int, var encoding: String): Post()
}
這在枚舉類中是不可能的。
封閉類和 when
封裝類別通常與 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()
}
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}")
}
讓我們按照以下所示在我們的 main
函式中執行 eval
函式。
fun main(args: Array) {
var circle = Shape.Circle(4.5f)
var square = Shape.Square(4)
var rectangle = Shape.Rectangle(4,5)
eval(circle)
eval(square)
eval(rectangle)
//eval(x) //編譯時錯誤。
}
//以下內容會被列印在控制台上:
//圓形面積為 63.585
//正方形面積為 16
//矩形面積為 20
注意: is
修飾符檢查類別是否為以下類型。 is
修飾符僅對類別需要,對於 Kotlin 物件不需要,如下所示:
sealed class Shape{
class Circle(var radius: Float): Shape()
class Square(var length: Int): Shape()
object Rectangle: Shape()
{
var length: Int = 0
var breadth : Int = 0
}
}
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}")
Shape.Rectangle -> println("Rectangle area is ${Shape.Rectangle.length*Shape.Rectangle.breadth}")
}
這就結束了 Kotlin 封裝類別教程。參考資料: Kotlin 文件
Source:
https://www.digitalocean.com/community/tutorials/kotlin-sealed-class