Menu
CoddyTech

Khối init và kiểm tra tính hợp lệ

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 4 trên 57.

Khối init chạy khi một instance được tạo, ngay sau khi các tham số của hàm khởi tạo được gán. Đây là nơi đặt code thiết lập không thể gói gọn trong một khai báo thuộc tính:

class Order(val id: Int, items: List<Int>) {
    val total: Int
    val count: Int

    init {
        total = items.sum()
        count = items.size
        println("created order $id")
    }
}

Bên trong main:

val o = Order(7, listOf(4, 6, 10))
println("${o.count} items, total ${o.total}")

Đầu ra:

created order 7
3 items, total 20

require(condition) { message } kiểm tra một đối số và ném IllegalArgumentException kèm thông báo khi điều kiện sai. Đặt câu lệnh này trong init nghĩa là không thể tạo một đối tượng không hợp lệ:

class Percentage(val value: Int) {
    init {
        require(value in 0..100) { "percentage must be 0-100, was $value" }
    }
}

Bên trong main:

println(Percentage(42).value)
try {
    Percentage(150)
} catch (e: IllegalArgumentException) {
    println(e.message)
}

Đầu ra:

42
percentage must be 0-100, was 150

Một lớp có thể có nhiều khối init; chúng chạy theo thứ tự, cùng với các phần khởi tạo thuộc tính, từ trên xuống dưới:

class Demo(name: String) {
    val first = "first: $name".also { println(it) }

    init { println("init 1") }

    val second = "second".also { println(it) }

    init { println("init 2") }
}

Bên trong main:

Demo("x")
println("done")

Đầu ra:

first: x
init 1
second
init 2
done

Việc xác thực trong init giúp đặt quy tắc ngay cạnh dữ liệu. Code nhận một đối tượng có thể tin tưởng đối tượng đó mà không cần kiểm tra lại:

class Email(val address: String) {
    init {
        require("@" in address) { "not an email: $address" }
    }
}
fun send(to: Email) { /* không cần kiểm tra lại địa chỉ */ }
challenge icon

Thử thách

Dễ

Hoàn thiện lớp (class) Password. Khối init dùng require để kiểm tra rằng văn bản có ít nhất 8 ký tự (thông báo too short) và chứa một chữ số (thông báo needs a digit), theo thứ tự đó. Thuộc tính strength được tính trong init: là strong khi văn bản cũng chứa một chữ cái viết hoa, nếu không thì là ok.

Code được cung cấp tạo một Password cho mỗi dòng đầu vào và in ra strength hoặc thông báo lỗi.

Code của bạn nằm trong Password.kt. Main.kt chứa code đầu vào/đầu ra được cung cấp và không thể chỉnh sửa.

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()
    for (line in input) {
        try {
            println(Password(line).strength)
        } catch (e: IllegalArgumentException) {
            println(e.message)
        }
    }
}
quiz iconTự kiểm tra

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

Tự luyện tập: Playground Kotlin