Chào mừng bạn đến với Cafedev, nơi chúng tôi truyền đạt những kiến thức sâu rộng về lập trình. Hôm nay, chúng ta sẽ cùng nhau khám phá Kotlin và những điều thú vị với Enum classes. Tại Cafedev, chúng tôi không chỉ chia sẻ thông tin mà còn tạo ra một cộng đồng lập trình sôi động. Đừng bỏ lỡ cơ hội học hỏi và trao đổi tại Cafedev, nơi đam mê lập trình được chia sẻ mỗi ngày. Hãy bắt đầu hành trình mới với Kotlin và Enum classes cùng Cafedev ngay hôm nay!

Trong các trường hợp sử dụng cơ bản nhất cho enum classes là triển khai các enum an toàn kiểu dữ liệu:

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


Mỗi hằng số enum là một đối tượng. Các hằng số enum được phân tách bằng dấu phẩy.
Vì mỗi enum là một thể hiện của lớp enum, nó có thể được khởi tạo như sau:

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

1. Anonymous classes

Các hằng số enum có thể khai báo các lớp ẩn danh riêng với các phương thức tương ứng, cũng như với việc ghi đè các phương thức cơ bản.

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

TALKING {
 override fun signal() = WAITING
};

abstract fun signal(): ProtocolState
}

Nếu lớp enum xác định bất kỳ thành viên nào, hãy phân tách định nghĩa hằng số từ định nghĩa thành viên bằng một dấu chấm phẩy.

2. Implementing interfaces trong enum classes

Một lớp enum có thể triển khai một interface (nhưng không thể kế thừa từ một lớp), cung cấp một triển khai chung của các thành viêninterface cho tất cả các mục nhập hoặc triển khai riêng lẻ cho mỗi mục nhập trong lớp ẩn danh của nó. Điều này được thực hiện bằng cách thêm cácinterface bạn muốn triển khai vào khai báo lớp enum như sau:

import java.util.function.BinaryOperator
import java.util.function.IntBinaryOperator

//sampleStart
enum class IntArithmetics : BinaryOperator, 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)
}
//sampleEnd

fun main() {
  val a = 13
  val b = 31
 for (f in IntArithmetics.entries) {
  println("$f($a, $b) = ${f.apply(a, b)}")
 }
}

Tất cả các lớp enum triển khai mặc định Comparableinterface. Các hằng số trong lớp enum được định nghĩa theo thứ tự tự nhiên. Để biết thêm thông tin, xem Ordering.

3. Làm việc với các hằng số enum

Enum classes trong Kotlin có các thuộc tính và phương thức tổng hợp để liệt kê các hằng số enum được định nghĩa và lấy một hằng số enum theo tên của nó. Các chữ ký của các phương thức này như sau (giả sử tên của lớp enum là EnumClass):

EnumClass.valueOf(value: String): EnumClass
EnumClass.entries: EnumEntries // specialized List

Dưới đây là một ví dụ minh họa:

enum class RGB { RED, GREEN, BLUE }

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"
}

Phương thức valueOf() ném một IllegalArgumentException nếu tên được chỉ định không khớp với bất kỳ hằng số enum nào được định nghĩa trong lớp.
Trước khi giới thiệu entries trong Kotlin 1.9.0, hàm values() được sử dụng để lấy một mảng các hằng số enum.
Mỗi hằng số enum cũng có các thuộc tính: nameordinal, để lấy tên và vị trí (bắt đầu từ 0) của nó trong khai báo lớp enum:

enum class RGB { RED, GREEN, BLUE }

fun main() {
//sampleStart
println(RGB.RED.name) // prints RED
println(RGB.RED.ordinal) // prints 0
//sampleEnd
}

Bạn có thể truy cập các hằng số trong một lớp enum theo cách chung bằng cách sử dụng các hàm enumValues()enumValueOf():

enum class RGB { RED, GREEN, BLUE }

inline fun > printAllValues() {
println(enumValues().joinToString { it.name })
}

printAllValues() // prints RED, GREEN, BLUE

Để biết thêm thông tin về các hàm inline và tham số kiểu reified, xem Các hàm inline.
Trong Kotlin 1.9.20, hàm enumEntries() được giới thiệu như một phương thức thay thế trong tương lai cho hàm enumValues().
Hàm enumValues() vẫn được hỗ trợ, nhưng chúng tôi khuyến nghị bạn sử dụng hàm enumEntries() thay vì vì nó có ít ảnh hưởng đến hiệu suất hơn. Mỗi lần bạn gọi enumValues(), một mảng mới được tạo ra, trong khi mỗi lần bạn gọi enumEntries(), cùng một danh sách được trả về mỗi lần, điều này hiệu quả hơn nhiều.
Ví dụ:

enum class RGB { RED, GREEN, BLUE }

@OptIn(ExperimentalStdlibApi::class)
inline fun > printAllValues() {
  println(enumEntries().joinToString { it.name })
}

printAllValues()
// RED, GREEN, BLUE



Cảm ơn bạn đã đồng hành cùng Cafedev trong hành trình khám phá Kotlin và Enum classes. Tại Cafedev, chúng tôi luôn mong muốn mang đến cho bạn những thông tin chất lượng và kiến thức sâu rộng về lập trình. Hãy tiếp tục theo dõi và tham gia vào cộng đồng lập trình sôi động của chúng tôi để cùng nhau trải nghiệm thế giới mã nguồn mở. Đừng quên ghé thăm Cafedev thường xuyên để cập nhật những bài viết mới nhất và chia sẻ đam mê lập trình. Cảm ơn bạn đã là một phần của Cafedev!

Các nguồn kiến thức MIỄN PHÍ VÔ GIÁ từ cafedev tại đây

Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của Cafedev để nhận được nhiều hơn nữa:

Chào thân ái và quyết thắng!

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!