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 hereCá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
falseThuộ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) : BoxBên trong main:
println(Tile(3, 4).area)Đầu ra:
12Mộ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.50Thử 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"}")
}
}
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ên2Thuộ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