Kotlin中的枚举类

Kotlin 枚举类(Enum Class)是一种特殊的类,用于表示固定数量的常量集合,例如一周的天数、方向(东、南、西、北)、状态(成功、失败、 pending)等。枚举类在编译时就已确定所有可能的实例,不能动态添加,因此非常适合用于表示一组有限的、明确的选项。

一、枚举类的基本定义

Kotlin 中使用 enum class 关键字定义枚举类,每个枚举常量都是枚举类的实例,之间用逗号分隔,末尾可加逗号或分号(可选)。

示例:简单枚举类

kotlin 复制代码
// 定义一个表示一周天数的枚举类
enum class DayOfWeek {
    MONDAY,    // 枚举常量:周一
    TUESDAY,   // 周二
    WEDNESDAY, // 周三
    THURSDAY,  // 周四
    FRIDAY,    // 周五
    SATURDAY,  // 周六
    SUNDAY     // 周日
}

说明

  • 每个枚举常量(如 MONDAY)都是 DayOfWeek 类的单例实例,无需手动 new 创建。
  • 枚举类默认继承自 Enum 类(Kotlin 自动处理),因此不能再继承其他类,但可以实现接口。

二、枚举类的核心特性与使用

1. 访问枚举常量

直接通过「枚举类名。常量名」访问枚举实例:

kotlin 复制代码
fun main() {
    val today = DayOfWeek.MONDAY
    println(today) // 输出:MONDAY(默认调用 toString() 方法)
}

2. 枚举常量的属性与方法

枚举类的每个实例都自带两个核心属性(继承自 Enum 类):

  • name:枚举常量的名称(字符串形式,如 "MONDAY")。
  • ordinal:枚举常量的索引(从 0 开始,如 MONDAYordinal 是 0,TUESDAY 是 1)。

此外,枚举类还可自定义属性和方法。

示例:带自定义属性和方法的枚举类

kotlin 复制代码
// 带参数的枚举类(每个常量可传入自定义属性)
enum class Direction(
    val chineseName: String, // 自定义属性:中文名称
    val degree: Int          // 自定义属性:角度(如东是 0°,北是 90°)
) {
    EAST("东", 0),
    SOUTH("南", 90),
    WEST("西", 180),
    NORTH("北", 270); // 末尾分号必须加(后面有方法时)

    // 自定义方法:获取反方向
    fun opposite(): Direction {
        return when (this) {
            EAST -> WEST
            SOUTH -> NORTH
            WEST -> EAST
            NORTH -> SOUTH
        }
    }

    // 重写父类方法(可选)
    override fun toString(): String {
        return "$chineseName($degree°)"
    }
}

fun main() {
    val dir = Direction.EAST
    println(dir.name)        // 输出:EAST(枚举常量名)
    println(dir.ordinal)     // 输出:0(索引)
    println(dir.chineseName) // 输出:东(自定义属性)
    println(dir.degree)      // 输出:0(自定义属性)
    println(dir.opposite())  // 输出:西(180°)(调用自定义方法)
    println(dir)             // 输出:东(0°)(调用重写的 toString())
}

注意

  • 枚举类的构造函数参数需在常量声明时传入(如 EAST("东", 0))。
  • 若枚举类有自定义方法,常量列表末尾必须加分号;)分隔。

3. 枚举类的常用方法

除了自定义方法,Enum 类还提供了一些实用的内置方法:

方法签名 功能说明 示例(以 Direction 为例)
values(): Array<T> 返回所有枚举常量的数组(按声明顺序排列) Direction.values()[EAST, SOUTH, WEST, NORTH]
valueOf(name: String): T 根据名称获取枚举常量(大小写敏感,不存在则抛异常) Direction.valueOf("WEST")WEST
compareTo(other: T): Int 比较两个枚举常量的 ordinal 差值 EAST.compareTo(WEST)0 - 2 = -2
name: String / ordinal: Int 获取名称 / 索引(前面已讲) -

示例:内置方法使用

kotlin 复制代码
fun main() {
    // 1. values():获取所有常量
    val allDirs = Direction.values()
    allDirs.forEach { println(it) } // 输出所有方向

    // 2. valueOf():按名称获取常量
    val west = Direction.valueOf("WEST")
    println(west) // 输出:西(180°)

    // 3. compareTo():比较索引
    val isEastBeforeSouth = Direction.EAST < Direction.SOUTH // 等价于 0 < 1
    println(isEastBeforeSouth) // 输出:true
}

4. 枚举类实现接口

枚举类不能继承其他类(默认继承 Enum),但可以实现一个或多个接口,且每个常量可单独实现接口方法(灵活适配不同行为)。

示例:枚举类实现接口

kotlin 复制代码
// 定义一个接口
interface Behavior {
    fun action(): String
}

// 枚举类实现接口(每个常量可自定义 action() 实现)
enum class Animal : Behavior {
    CAT {
        override fun action(): String {
            return "猫:喵喵叫"
        }
    },
    DOG {
        override fun action(): String {
            return "狗:汪汪叫"
        }
    },
    BIRD {
        override fun action(): String {
            return "鸟:叽叽喳喳"
        }
    }
}

fun main() {
    val animal = Animal.DOG
    println(animal.action()) // 输出:狗:汪汪叫
}

三、枚举类的高级用法

1. 带抽象方法的枚举类

枚举类可以包含抽象方法,此时每个枚举常量必须重写该抽象方法(类似接口的实现)。

示例:带抽象方法的枚举

kotlin 复制代码
enum class Operation {
    ADD {
        override fun calculate(a: Int, b: Int): Int = a + b
    },
    SUBTRACT {
        override fun calculate(a: Int, b: Int): Int = a - b
    },
    MULTIPLY {
        override fun calculate(a: Int, b: Int): Int = a * b
    };

    // 抽象方法(必须被所有常量重写)
    abstract fun calculate(a: Int, b: Int): Int
}

fun main() {
    val op = Operation.MULTIPLY
    println(op.calculate(3, 4)) // 输出:12
}

2. 枚举常量作为参数

枚举类的实例可作为函数参数,限制输入为固定的常量集合,提高代码安全性。

示例:枚举作为函数参数

kotlin 复制代码
// 函数参数类型为枚举类 DayOfWeek
fun isWeekend(day: DayOfWeek): Boolean {
    return day == DayOfWeek.SATURDAY || day == DayOfWeek.SUNDAY
}

fun main() {
    println(isWeekend(DayOfWeek.FRIDAY))  // 输出:false
    println(isWeekend(DayOfWeek.SATURDAY))// 输出:true
}

四、枚举类 vs 密封类(Sealed Class)

Kotlin 中还有一个类似的概念「密封类(sealed class)」,两者都用于表示有限的选项,但有以下区别:

特性 枚举类(Enum Class) 密封类(Sealed Class)
实例数量 编译时固定,不能动态添加 子类数量固定(必须在同一文件或子文件中定义)
继承关系 不能继承其他类,可实现接口 可继承其他类,可被其子类继承(子类可为任意类型)
实例类型 所有常量都是枚举类本身的实例 每个子类都是独立的类型(可包含不同属性和方法)
适用场景 表示一组无状态的常量(如状态、类型) 表示一组有状态的变体(如不同类型的事件、数据)

示例:密封类(对比枚举)

kotlin 复制代码
// 密封类(表示不同类型的网络请求结果)
sealed class Result {
    data class Success(val data: String) : Result() // 成功(带数据)
    data class Error(val code: Int, val msg: String) : Result() // 失败(带错误码和信息)
    object Loading : Result() // 加载中(无状态)
}

// 使用密封类(编译器会自动检查所有可能的情况,避免遗漏)
fun handleResult(result: Result) {
    when (result) {
        is Result.Success -> println("成功:${result.data}")
        is Result.Error -> println("失败:${result.code} - ${result.msg}")
        Result.Loading -> println("加载中...")
    }
}

总结

  • 若需表示「无状态的常量集合」(如方向、状态码),用枚举类
  • 若需表示「有状态的变体集合」(如不同类型的结果、事件),用密封类

五、枚举类的常见应用场景

  1. 状态表示 :如 STATUS_SUCCESSSTATUS_FAILEDSTATUS_PENDING
  2. 类型分类 :如 TYPE_TEXTTYPE_IMAGETYPE_VIDEO(表示消息类型)。
  3. 配置选项 :如 THEME_LIGHTTHEME_DARKTHEME_SYSTEM(主题配置)。
  4. 有限集合:如一周天数、月份、方向等。

六、注意事项

  1. 枚举常量的 nameordinalfinal 的,不能修改。
  2. valueOf() 方法对名称大小写敏感,若传入不存在的名称,会抛出 IllegalArgumentException,建议结合 try-catch 使用或提前判断。
  3. 枚举类的实例是单例的,多次访问同一个常量会返回同一个对象。

总结

Kotlin 枚举类是表示固定常量集合的强大工具,支持自定义属性、方法、接口实现和抽象方法,用法灵活且类型安全。在需要限制输入为有限选项的场景中,枚举类是替代字符串 / 整数常量的最佳选择,能显著提高代码的可读性和可维护性。

相关推荐
qq_12498707536 小时前
基于springboot的建筑业数据管理系统的设计与实现(源码+论文+部署+安装)
java·spring boot·后端·毕业设计
IT_陈寒7 小时前
Vite 5.0实战:10个你可能不知道的性能优化技巧与插件生态深度解析
前端·人工智能·后端
z***3357 小时前
SQL Server2022版+SSMS安装教程(保姆级)
后端·python·flask
zxguan8 小时前
Springboot 学习 之 下载接口 HttpMessageNotWritableException
spring boot·后端·学习
加洛斯8 小时前
告别数据混乱!精通Spring Boot序列化与反序列化
后端
爱分享的鱼鱼8 小时前
Spring 事务管理、数据验证 、验证码验证逻辑设计、异常回退(Java进阶)
后端
程序员西西8 小时前
Spring Boot中支持的Redis访问客户端有哪些?
java·后端
空白诗8 小时前
tokei 在鸿蒙PC上的构建与适配
后端·华为·rust·harmonyos
q***58198 小时前
SpringBoot返回文件让前端下载的几种方式
前端·spring boot·后端