22:kotlin 类和对象 -- 枚举类(Enum classes)

枚举类最基本的用例是实现类型安全的枚举

enum class Direction {
    NORTH, SOUTH, WEST, EAST
}

每个枚举常量都是一个对象。枚举常量以逗号分隔。

由于每个枚举都是枚举类的一个实例,因此可以将其初始化为

enum class Color(val rgb: Int) {
    RED(0xFF0000),
    GREEN(0x00FF00),
    BLUE(0x0000FF)
}

匿名类

枚举常量可以声明自己的匿名类,这些匿名类具有对应的方法,并且可以重写基础方法

enum class ProtocolState {
    WAITING {
        override fun signal() = TALKING
    },

    TALKING {
        override fun signal() = WAITING
    };	// 分号

    abstract fun signal(): ProtocolState
}

如果枚举类定义了任何成员,则用分号将常量定义与成员定义分开

在枚举类中实现接口

枚举类可以实现一个接口(但不能继承自类)

enum class IntArithmetics : BinaryOperator<Int>, IntBinaryOperator {
    PLUS {
        override fun apply(t: Int, u: Int): Int = t + u	// 实现接口方法
    },
    TIMES {
        override fun apply(t: Int, u: Int): Int = t * u
    };

    override fun applyAsInt(t: Int, u: Int) = apply(t, u)	// 为所有枚举实例实现方法
}

所有枚举类默认实现了Comparable接口

使用枚举常量

enum class RGB { RED, GREEN, BLUE }
  • RGB.entries - 获取所有枚举实例
  • RGB.valueOf("RED") - 通过字符串获取相应的枚举实例
fun main() {
    for (color in RGB.entries) println(color.toString()) // prints RED, GREEN, BLUE
    println("The first color is: ${RGB.valueOf("RED")}") // prints "The first color is: RED"
}

如果.valueOf("")与所有枚举实例都不匹配,则报错IllegalArgumentException

1.9.0版本之前,values()代替entries

枚举有nameordinal属性,一个代表名字,一个代表枚举实例在枚举类中的索引(从0开始)

println(RGB.RED.name)    // RED
println(RGB.RED.ordinal) // 0

可以使用enumValues()enumValueOf()函数以通用的方式访问枚举类中的常量

enum class RGB { RED, GREEN, BLUE }

fun main() {
    println(enumValues<RGB>().joinToString { it->it.name })
     //  RED, GREEN, BLUE
}

1.9.20版本中,引入了enumEntries()函数作为enumValues()函数的未来替代品。

虽然enumValues()函数仍然受到支持,建议改用enumEntries()函数,因为它对性能的影响较小。每次调用enumValues()时都会创建一个新的数组,而每次调用enumEntries()时都会返回相同的列表,这更加高效

enum class RGB { RED, GREEN, BLUE }

fun main() {
    @OptIn(ExperimentalStdlibApi::class)
    println(enumEntries<RGB>())
    // [RED, GREEN, BLUE]
}

enumEntries()函数是实验性的。要使用它,需要使用@OptIn(ExperimentalStdlibApi)进行选择,并将语言版本设置为至少1.9

你可能感兴趣的:(kotlin教程,kotlin)