Nhiều giao diện
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 24 trên 57.
Một lớp có thể triển khai nhiều giao diện, ngăn cách bằng dấu phẩy. Lớp đó phải triển khai các thành viên của tất cả các giao diện:
interface Switchable {
var isOn: Boolean
fun toggle() { isOn = !isOn }
}
interface Dimmable {
var level: Int
}
class Lamp : Switchable, Dimmable {
override var isOn = false
override var level = 100
}Bên trong main:
val lamp = Lamp()
lamp.toggle()
lamp.level = 40
println("${lamp.isOn} ${lamp.level}")Đầu ra:
true 40Một lớp có thể kế thừa một lớp và triển khai các giao diện trong cùng một phần khai báo. Chỉ lớp cha mới có lời gọi hàm khởi tạo:
open class Device(val name: String)
interface Rechargeable {
fun charge(): String
}
class Phone(name: String) : Device(name), Rechargeable {
override fun charge() = "$name is charging"
}Bên trong main:
println(Phone("Pixel").charge())Đầu ra:
Pixel is chargingKhi hai giao diện đều cung cấp phần thân mặc định cho cùng một phương thức, lớp phải ghi đè phương thức đó và quyết định cần làm gì. super<Name>.method() gọi phiên bản của một giao diện cụ thể:
interface Camera {
fun describe() = "takes photos"
}
interface Telephone {
fun describe() = "makes calls"
}
class SmartPhone : Camera, Telephone {
override fun describe() = super<Telephone>.describe() + " and " + super<Camera>.describe()
}Bên trong main:
println(SmartPhone().describe())Đầu ra:
makes calls and takes photosMột giao diện có thể mở rộng các giao diện khác. Một lớp triển khai giao diện kết hợp phải cung cấp các thành viên của tất cả giao diện đó và được xem là từng giao diện trong số đó:
interface Named {
val name: String
}
interface Contact : Named {
val email: String
fun card() = "$name <$email>"
}
class Person(override val name: String, override val email: String) : ContactBên trong main:
val ada = Person("Ada", "ada@example.com")
val named: Named = ada
println(ada.card())
println(named.name)Đầu ra:
Ada <ada@example.com>
AdaThử thách
DễHai giao diện mô tả một thiết bị thông minh: Switchable yêu cầu isOn (một Boolean chỉ đọc đối với bên gọi) và toggle(), còn Dimmable yêu cầu thuộc tính brightness có thể ghi. Hãy để SmartLamp triển khai cả hai: đèn ban đầu tắt với độ sáng 100, toggle() bật hoặc tắt đèn, bộ thiết lập giới hạn độ sáng nằm ngoài khoảng từ 0 đến 100, và status() trả về on 70% hoặc off.
Code được cung cấp đọc các lệnh toggle hoặc một số độ sáng, áp dụng chúng cho một chiếc đèn rồi in ra status() sau mỗi lệnh, sau đó kiểm tra xem đèn có thuộc kiểu Switchable và Dimmable hay không.
Code của bạn nằm trong các tệp Switchable.kt, Dimmable.kt và SmartLamp.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 đã cho: giữ nguyên
val input = generateSequence(::readLine).toList()
val lamp = SmartLamp()
for (cmd in input) {
if (cmd == "toggle") lamp.toggle() else lamp.brightness = cmd.toInt()
println(lamp.status())
}
println("switchable: ${(lamp as Any) is Switchable}, dimmable: ${(lamp as Any) is Dimmable}")
}
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