enum类
Kotlin中的枚举类实际就是普通类中封装了一个companion object,其中包含类多个本类得到实例,用来表现枚举。
enum class MyName(val i: Int){
//枚举其实相当于普通类定义了一个companion object
//并且在Object中声明了多个本类的示例
JIM(0),JAN(1), MIKE(2);
fun test(){
JAN.test()
}
}
等价于:
class TestEnum(val i: Int){
companion object{
val JIM: TestEnum = TestEnum(0)
val JAN: TestEnum = TestEnum(1)
val MIKE: TestEnum = TestEnum(2)
}
fun test(){
JAN.test()
}
}
我们可以把enum当做companion object使用:
fun main(args: Array<String>) {
//获取到枚举变量对应的常量的值
MyName.JAN.ordinal
//获取所有的枚举变量
MyName.values()
//获取指定的枚举变量
MyName.valueOf("JIM")
}
使用枚举开销较大,因为枚举类中实际包含了多个本类的对象实例;
sealed类
与enum的对比:
- enum适合用来表示状态,因为状态无论何时,全局只有一个,而sealed适合用来表示类似指令,这种全局同一时间可能存在多个的情况。
- sealed类似于枚举,其规定了子类的种类的限制,当子类可以有多个实例时,定义为class,否则定义为object(enum:实例可数,sealed:子类可数)。
- sealed的子类当不需要保存状态时,即所有的实例都保有相同的状态时用object,如果同一种子类需要有多种状态,则用class。
sealed定义子类种类的限制
enum定义的时候,声明了enum类自身的多个静态实例,用来表示多种状态,每种状态只能有一个实例,由于每个实例都是枚举自身,所以其构造参数一致;
sealed定义了子类种类的限制,不同于enum,其中并没有子类的实例,而只是子类的声明,子类可以自定义构造方法参数列表,并且子类可以根据自身情况,决定要存在一个实例(object),还是多个实例(class).
比如:播放音乐
sealed class PlayerCmd
//如果该类需要定义多个实例,则声明为class
class Play(val url: String, val position: Long = 0): PlayerCmd()
class Seek(val position: Long): PlayerCmd()
//如果该类只能定义一个实例,则声明为object
object Pause: PlayerCmd()
object Resume: PlayerCmd()
object Stop : PlayerCmd()
我们需要新的播放状态时,我们只需要new一个新的Play实例,传进来即可,对于停止stop操作,是全局的操作,我们只需要一个实例.