Lớp enum
Thuộc phần Lập trình hướng đối tượng trong hành trình Kotlin của Coddy. Bài học 33 trên 57.
enum class khai báo một kiểu có một tập giá trị cố định, gọi là các hằng số. Mỗi hằng số là một đối tượng của enum, có name và ordinal, tức vị trí bắt đầu từ 0. entries liệt kê các hằng số theo thứ tự:
enum class Direction { NORTH, EAST, SOUTH, WEST }Bên trong main:
val d = Direction.EAST
println(d)
println(d.ordinal)
println(Direction.entries)Đầu ra:
EAST
1
[NORTH, EAST, SOUTH, WEST]Các hằng số enum có thể có thuộc tính được truyền vào hàm khởi tạo của enum, và enum có thể khai báo các phương thức. Dấu chấm phẩy kết thúc danh sách hằng số trước các thành viên:
enum class Coin(val cents: Int) {
PENNY(1), NICKEL(5), DIME(10), QUARTER(25);
fun label() = "${name.lowercase()} ($cents c)"
}Bên trong main:
println(Coin.DIME.label())
println(Coin.entries.sumOf { it.cents })Đầu ra:
dime (10 c)
41Một câu lệnh when dùng với enum liệt kê mọi hằng số thì không cần else, và trình biên dịch sẽ báo nếu thiếu một hằng số. valueOf("SOUTH") tìm hằng số theo đúng tên và gây ngoại lệ nếu không tìm thấy, vì vậy đầu vào thường được đối chiếu bằng entries.find:
enum class Direction { NORTH, EAST, SOUTH, WEST }
fun turnRight(d: Direction) = when (d) {
Direction.NORTH -> Direction.EAST
Direction.EAST -> Direction.SOUTH
Direction.SOUTH -> Direction.WEST
Direction.WEST -> Direction.NORTH
}
fun parse(text: String) = Direction.entries.find { it.name == text.uppercase() }Bên trong main:
println(turnRight(Direction.valueOf("SOUTH")))
println(parse("north"))
println(parse("up"))Đầu ra:
WEST
NORTH
nullMột hằng số có thể có phần thân riêng và ghi đè một phương thức trong đó. Khai báo phương thức abstract trong enum buộc mọi hằng số phải triển khai phương thức đó:
enum class Op(val symbol: String) {
PLUS("+") {
override fun apply(a: Int, b: Int) = a + b
},
TIMES("*") {
override fun apply(a: Int, b: Int) = a * b
};
abstract fun apply(a: Int, b: Int): Int
}Bên trong main:
for (op in Op.entries) println("6 ${op.symbol} 3 = ${op.apply(6, 3)}")Đầu ra:
6 + 3 = 9
6 * 3 = 18Thử thách
DễHoàn thiện enum Size với các hằng số SMALL (250 ml, giá 300), MEDIUM (350 ml, 380) và LARGE (500 ml, 450), giá tính bằng cent. label() trả về medium (350 ml): 3.80, còn upsize() trả về kích cỡ lớn hơn tiếp theo, hoặc giữ nguyên kích cỡ nếu là LARGE. parse(text) của companion tìm kích cỡ theo tên, không phân biệt chữ hoa chữ thường, hoặc theo chữ cái đầu tiên (s, M), và trả về null nếu không tìm thấy.
Code được cung cấp đọc các đơn hàng như medium, L hoặc up small (đồ uống được tăng kích cỡ), rồi in từng nhãn hoặc unknown size x, cuối cùng in total: 11.10.
Code của bạn nằm trong Size.kt. Main.kt chứa code đầu vào/đầu ra được cung cấp và bạn không thể chỉnh sửa tệp này.
Tự làm thử
fun main() {
// Đoạn code đầu vào/đầu ra có sẵn: giữ nguyên
val input = generateSequence(::readLine).toList()
var total = 0
for (line in input) {
val upsize = line.startsWith("up ")
val size = Size.parse(line.removePrefix("up "))
if (size == null) {
println("unknown size $line")
continue
}
val chosen = if (upsize) size.upsize() else size
println(chosen.label())
total += chosen.price
}
println("total: %d.%02d".format(total / 100, total % 100))
}
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Lập trình hướng đối tượng
1Lớp và đối tượng
Làm việc với tệpĐịnh nghĩa lớpHàm khởi tạo chínhKhối init và kiểm tra tính hợp lệHàm khởi tạo phụÔn tập: thẻ thư viện4Kế thừa
Lớp mở và lớp conGhi đè thành viênsuper và hàm khởi tạoLớp trừu tượngÔn tập: Danh bạ nhân viên7Các lớp đặc biệt
Lớp dữ liệuLớp enumHệ phân cấp sealedequals, hashCode, toStringÔn tập: Theo dõi đơn hàng2Thuộc tính và tính đóng gói
Trình truy cập tùy chỉnhBộ sửa đổi phạm vi truy cậpSetter riêng tưlazy và lateinitÔn tập: tài khoản ngân hàng5Giao diện
Khai báo giao diệnPhương thức mặc địnhNhiều giao diệnGiao diện như kiểu dữ liệuÔn tập: Phương thức thanh toánTự luyện tập: Playground Kotlin