----《第一季Kotlin崛起:次世代Android开发 》学习笔记
总目录:每天学一点 Kotlin ---- 目录
上一篇:每天学一点 Kotlin -- 多彩的类:数据类
下一篇:每天学一点 Kotlin -- 多彩的类:泛型
1. 密封类
1.1 密封类主要在里面封装了各种各样的类,也就是说,它是一个大容器,在里面放了一个又一个的类元素,这些元素就像容器类内部的属性一般,我们可以把类当作这个容器的组成部分。
1.2 声明一个密封类:在类定义前用关键字 sealed 来修饰。
2. 举个栗子:
2.1 不使用密封类的情况下:
open class FruitForSealed{}
class AppleForSealed : FruitForSealed(){
fun operate() = println("我是一个苹果")
}
class BananaForSealed : FruitForSealed(){
fun operate() = println("我是一个香蕉")
}
class WaterMelonForSealed : FruitForSealed(){
fun operate() = println("我是一块西瓜")
}
fun testFruitForSealed(fruit: FruitForSealed){
when(fruit){
is AppleForSealed -> fruit.operate()
is BananaForSealed -> fruit.operate()
is WaterMelonForSealed -> fruit.operate()
else -> null
}
}
fun main() {
val f = BananaForSealed()
testFruitForSealed(f)
}
打印结果:
我是一个香蕉
2.2 使用密封类的情况:
sealed class FruitForSealed1{
class Apple: FruitForSealed1(){
fun operate() = println("this is apple")
}
class Banana: FruitForSealed1(){
fun operate() = println("this is banana")
}
class Pair: FruitForSealed1(){
fun operate() = println("this is pair")
}
}
fun testFruitForSealed01(){
val fruit1 = FruitForSealed1.Apple()
fruit1.operate()
val fruit2 = FruitForSealed1.Banana()
fruit2.operate()
}
fun main() {
testFruitForSealed01()
}
打印结果:
this is apple
this is banana
可以看出,使用密封类里面的类和普遍类是一样的。
2.3 给上面的类定义一个总的操作函数:
sealed class FruitForSealed1 {
class Apple : FruitForSealed1() {
fun operate() = println("this is apple")
}
class Banana : FruitForSealed1() {
fun operate() = println("this is banana")
}
class Pair : FruitForSealed1() {
fun operate() = println("this is pair")
}
}
fun testFruitOperate1(fruit: FruitForSealed1) = when (fruit) {
is FruitForSealed1.Apple -> fruit.operate()
is FruitForSealed1.Banana -> fruit.operate()
is FruitForSealed1.Pair -> fruit.operate()
}
fun main() {
val f = FruitForSealed1.Pair()
testFruitOperate1(f)
}
打印结果:
this is pair
函数传入的参数没有变化,而且内部仍然是 when 表达式,但是和 2.1 相比,不需要 else 语句了。因为在 when 中说明了 Apple,Banana 和 Pair 类对应的操作,也就是把容器里面的小类型全部列举了,不会再有其他的情况了。
2.4 在 Kotlin1.1 之后,密封类还可以用继承的写法:
sealed class FruitForSealed2 {}
class AppleForSealed2 : FruitForSealed2() {
fun operate() = println("我是一个 AppleForSealed2")
}
class BananaForSealed2 : FruitForSealed2() {
fun operate() = println("我是一个 BananaForSealed2")
}
class WaterMelonForSealed2 : FruitForSealed2() {
fun operate() = println("我是一块 WaterMelonForSealed2")
}
2.5 密封类就像在写嵌套类,也像是在写枚举类。当然,这些都是互通的,不过还是有区别的:密封类是枚举类的扩展,每个枚举常量只有一个实例,而密封类的一个子类有可包含状态的多个实例。也就是说,对密封类的子类进行多次实例化产生多个不同的实例,而这个在枚举类中是无法实现的。