Khai báo 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 22 trên 57.
Một giao diện (interface) liệt kê những gì một kiểu dữ liệu có thể làm mà không nói cách thực hiện. Giao diện khai báo các phương thức và thuộc tính mà mọi lớp triển khai giao diện đều phải cung cấp. Một lớp triển khai giao diện bằng dấu hai chấm, giống như với lớp cha, nhưng không có dấu ngoặc đơn vì giao diện không có hàm khởi tạo:
interface Drawable {
fun draw(): String
}
class Circle(val radius: Int) : Drawable {
override fun draw() = "circle with radius $radius"
}
class Line(val length: Int) : Drawable {
override fun draw() = "-".repeat(length)
}Bên trong main:
println(Circle(3).draw())
println(Line(5).draw())Đầu ra:
circle with radius 3
-----Một giao diện cũng có thể khai báo thuộc tính. Lớp cung cấp các thuộc tính đó dưới dạng thuộc tính hàm khởi tạo, thuộc tính được lưu trữ hoặc getter; bản thân giao diện không lưu trữ gì:
interface Vehicle {
val wheels: Int
val label: String
}
class Car(override val label: String) : Vehicle {
override val wheels = 4
}
class Bike : Vehicle {
override val wheels = 2
override val label: String
get() = "bike on $wheels wheels"
}Bên trong main:
println("${Car("taxi").label}: ${Car("taxi").wheels}")
println(Bike().label)Đầu ra:
taxi: 4
bike on 2 wheelsPhải triển khai mọi thành viên mà giao diện khai báo, mỗi thành viên đều cần có override, nếu không lớp sẽ không biên dịch được. Không thể khởi tạo một giao diện:
interface Speaker {
fun speak(): String
val volume: Int
}
// class Mute : Speaker { override fun speak() = "" } // lỗi: chưa triển khai volume
// class Loud : Speaker() { ... } // lỗi: interface không có hàm khởi tạo
// val s = Speaker() // lỗi: không thể tạo interfaceCả interface lẫn lớp trừu tượng đều khai báo các thành viên không có phần thân. Interface không có hàm khởi tạo và không lưu trạng thái, còn một lớp có thể triển khai nhiều interface nhưng chỉ kế thừa một lớp. Dùng interface cho một khả năng mà các lớp không liên quan cùng có, chẳng hạn như Drawable hoặc Comparable, và dùng lớp trừu tượng làm lớp cơ sở chung có trạng thái.
interface Drawable { fun draw(): String } // một khả năng
abstract class Shape(val name: String) { abstract fun area(): Double } // một lớp cơ sở có trạng thái
class Square(val s: Double) : Shape("square"), Drawable { // một lớp, nhiều giao diện
override fun area() = s * s
override fun draw() = "[]"
}Thử thách
DễKhai báo các thành viên của giao diện Shape: thuộc tính chỉ đọc name và các phương thức area(), perimeter(), cả hai đều trả về Double. Hãy để Rectangle(width, height) (tên rectangle) và Circle(radius) (tên circle, sử dụng Math.PI) triển khai các thành viên này. Sau đó hoàn thành describe(shape), hàm này trả về rectangle: area 12.00, perimeter 14.00 với hai chữ số thập phân, chỉ sử dụng các thành viên của Shape.
Code được cung cấp đọc các dòng r,3,4 hoặc c,2, tạo hình tương ứng và in ra describe(shape).
Code của bạn nằm trong các tệp Shape.kt, Rectangle.kt, Circle.kt và Functions.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 đã cung cấp: giữ nguyên
val input = generateSequence(::readLine).toList()
for (line in input) {
val p = line.split(",").map { it.trim() }
val shape: Shape = if (p[0] == "r") Rectangle(p[1].toDouble(), p[2].toDouble()) else Circle(p[1].toDouble())
println(describe(shape))
}
}
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