Menu
CoddyTech

Phương thức mặc định

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

Phương thức trong interface có thể có phần thân. Phần triển khai mặc định này được dùng bởi mọi lớp không ghi đè nó:

interface Greeter {
    val name: String
    fun greet() = "Hello, I am $name"
}
class Robot(override val name: String) : Greeter
class Pirate(override val name: String) : Greeter {
    override fun greet() = "Ahoy! $name here"
}

Bên trong main:

println(Robot("R2").greet())
println(Pirate("Anne").greet())

Đầu ra:

Hello, I am R2
Ahoy! Anne here

Các phương thức mặc định được viết dựa trên những thành viên khác của giao diện. Một lớp cung cấp một vài thành viên có sự khác biệt và nhận các thành viên còn lại:

interface Priced {
    val cents: Int
    fun formatted() = "$%d.%02d".format(cents / 100, cents % 100)
    fun isAffordable(budget: Int) = cents <= budget
}
class Coffee : Priced {
    override val cents = 450
}

Bên trong main:

val c = Coffee()
println(c.formatted())
println(c.isAffordable(400))

Đầu ra:

$4.50
false

Thuộc tính có thể có getter mặc định, nhưng interface không có trường lưu trữ phía sau nên không thể lưu giá trị. Thuộc tính có giá trị khởi tạo sẽ không biên dịch; getter tính giá trị thì được:

interface Box {
    val width: Int
    val height: Int
    val area: Int
        get() = width * height
    // val count = 0      // lỗi: không thể khởi tạo thuộc tính trong giao diện
}
class Tile(override val width: Int, override val height: Int) : Box

Bên trong main:

println(Tile(3, 4).area)

Đầu ra:

12

Một phương thức ghi đè vẫn có thể dùng cách triển khai mặc định. Bên trong lớp, super.method() gọi phiên bản của interface:

interface Priced {
    val cents: Int
    fun formatted() = "$%d.%02d".format(cents / 100, cents % 100)
}
class Coffee : Priced {
    override val cents = 450
    override fun formatted() = "coffee " + super.formatted()
}

Bên trong main:

println(Coffee().formatted())

Đầu ra:

coffee $4.50
challenge icon

Thử thách

Dễ

Giao diện Priced có price (tính bằng cent). Hãy thêm phương thức mặc định formatted() trả về $4.50 và phương thức mặc định isAffordable(budget) trả về kết quả cho biết giá có thấp hơn hoặc bằng ngân sách hay không. Coffee có giá 450 và thay thế formatted() bằng coffee $4.50, đồng thời dùng lại phương thức mặc định thông qua super. Sandwich(price) dùng cả hai phương thức mặc định.

Code được cung cấp đọc ngân sách tính bằng cent, sau đó đọc các dòng coffee hoặc sandwich,650. Với mỗi món, code in ra formatted() và yes hoặc no.

Code của bạn nằm trong Priced.kt, Coffee.kt và Sandwich.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()
    val budget = input[0].toInt()
    for (line in input.drop(1)) {
        val p = line.split(",")
        val item: Priced = if (p[0] == "coffee") Coffee() else Sandwich(p[1].toInt())
        println("${item.formatted()} ${if (item.isAffordable(budget)) "yes" else "no"}")
    }
}
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