一、声明方式及枚举常量
- 关键字:
enum- 枚举常量:即枚举类下的对象,每个枚举类包含0个到多个枚举常量。
1.1、声明
enum关键字在类头中的class关键字前面
声明格式:
enum class 类名{
...
}
1.2、枚举常量
枚举类中的每一个枚举常量都是一个对象,并且他们之间用逗号分隔。
例:
/**
* 例:关于一个网络请求结果的枚举类
*/
enum class State{
/*
NORMAL : 正常
NO_DATA : 数据为空
NO_INTERNET : 网络未连接
ERROR : 错误
OTHER : 其他
*/
NORMAL,NO_DATA,NO_INTERNET,ERROR,OTHER
}
1.3、访问枚举常量
不需要实例化枚举类就可以访问枚举常量
使用方式为:
枚举类名.枚举常量.属性
通过上面例子来实例讲解:
// 使用中缀符号访问枚举常量
State.NORMAL.name
State.NO_DATA.name
State.NO_INTERNET.name
State.ERROR.name
State.OTHER.name
这里只是让大家明白怎样去访问一个枚举常量。没有讲解到枚举常量的使用。枚举常量的使用请大家耐心的看下去。在下面会详细介绍怎样去使用它。
二、枚举常量的初始化
因为每一个枚举都是枚举类的实例,所以他们可以是初始化过的。
例:
enum class Color(var argb : Int){
RED(0xFF0000),
WHITE(0xFFFFFF),
BLACK(0x000000),
GREEN(0x00FF00)
}
三、枚举常量的匿名类
- 要实现枚举常量的匿名类,则必须提供一个抽象方法(必须重写的方法)。且该方法定义在枚举类内部。而且必须在枚举变量的后面。
- 枚举变量之间使用逗号(,)分割开。但是最后一个枚举变量必须使用分号结束。不然定义不了抽象方法。
- 在上面已经说过,每一个枚举常量就是一个对象。
例:
fun main(args: Array<String>) {
ConsoleColor.BLACK.print()
}
enum class ConsoleColor(var argb : Int){
RED(0xFF0000){
override fun print() {
println("我是枚举常量 RED ")
}
},
WHITE(0xFFFFFF){
override fun print() {
println("我是枚举常量 WHITE ")
}
},
BLACK(0x000000){
override fun print() {
println("我是枚举常量 BLACK ")
}
},
GREEN(0x00FF00){
override fun print() {
println("我是枚举常量 GREEN ")
}
};
abstract fun print()
}
输出结果为:
我是枚举常量 BLACK
四、枚举类的使用
- 每个枚举常量都包含两个属性:name(枚举常量名)和ordinal(枚举常量位置)
- 提供了values()和valueOf()方法来检测指定的名称与枚举类中定义的任何枚举常量是否匹配。
- 自 Kotlin 1.1起,可以使用 enumValues()和 enumValueOf()函数以泛型的方式访问枚举类中的常量。
4.1、访问枚举变量属性
例:
fun main(args: Array<String>) {
println("name = " + Color.RED.name + "\tordinal = " + Color.RED.ordinal)
println("name = " + Color.WHITE.name + "\tordinal = " + Color.WHITE.ordinal)
println("name = " + Color.BLACK.name + "\tordinal = " + Color.BLACK.ordinal)
println("name = " + Color.GREEN.name + "\tordinal = " + Color.GREEN.ordinal)
}
enum class Color(var argb : Int){
RED(0xFF0000),
WHITE(0xFFFFFF),
BLACK(0x000000),
GREEN(0x00FF00)
}
输出结果为:
name = RED ordinal = 0
name = WHITE ordinal = 1
name = BLACK ordinal = 2
name = GREEN ordinal = 3
4.2、使用enumValues()和 enumValueOf()访问
例: 枚举类还是上面例子中的Color类
println(enumValues<Color>().joinToString { it.name })
println(enumValueOf<Color>("RED"))
输出结果为:
RED, WHITE, BLACK, GREEN
RED
4.3、使用valueOf()和values()检测
例:
println(Color.valueOf("RED"))
println(Color.values()[0])
println(Color.values()[1])
println(Color.values()[2])
println(Color.values()[3])
输出结果为:
RED
RED
WHITE
BLACK
GREEN
其中,若使用Color.valueOf("不存在的枚举常量"),则会抛出IllegalArgumentException 异常,即枚举变量不存在。若使用Color.values()[大于枚举常量位置],则会抛出下标越界异常。
五、枚举类的源码分析
- 即
Enum.kt这个源文件。
在这里我大致的说明一下这个源文件的方法、属性等。有兴趣的可以去看看这个源文件。其实里面也没几个方法。
5.1、默认实现了companion object {}
- 这也是我们访问枚举常量无需实例化枚举类的原因。
5.2、仅提供了两个属性
- 即我们上面用到的枚举常量名称(name)和枚举常量位置(ordinal) 贴上这两个属性的源码:
/**
* Returns the name of this enum constant, exactly as declared in its enum declaration.
*/
public final val name: String
/**
* Returns the ordinal of this enumeration constant (its position in its enum declaration, where the initial constant
* is assigned an ordinal of zero).
*/
public final val ordinal: Int
5.3、实现了Comparable接口
- 这也是我们能获取枚举常量位置的原因。
这是Enum.kt源文件。让大家看看它实现了Comparable接口
public abstract class Enum<E : Enum<E>>(name: String, ordinal: Int): Comparable<E>{
...
}
再来看看Comparable.kt里面做了些什么。其实里面就提供了一个方法罢了...
public interface Comparable<in T> {
/**
* Compares this object with the specified object for order. Returns zero if this object is equal
* to the specified [other] object, a negative number if it's less than [other], or a positive number
* if it's greater than [other].
*/
public operator fun compareTo(other: T): Int
}