Trình truy cập tùy chỉ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 7 trên 57.
Mỗi thuộc tính trong Kotlin đều có một getter, và mỗi var cũng có một setter. Theo mặc định, chúng đọc và ghi giá trị được lưu trữ. Getter tùy chỉnh sẽ tính giá trị mỗi khi bạn đọc:
class Rectangle(var width: Int, var height: Int) {
val area: Int
get() = width * height
}Bên trong main:
val r = Rectangle(3, 4)
println(r.area)
r.width = 10
println(r.area)Đầu ra:
12
40Setter tùy chỉnh chạy code mỗi khi thuộc tính được gán giá trị. Bên trong setter, value là giá trị được gán và field là giá trị được lưu phía sau thuộc tính, còn gọi là trường hỗ trợ:
class Thermostat {
var target = 20
set(value) {
field = value.coerceIn(10, 30)
}
}Bên trong main:
val t = Thermostat()
t.target = 42
println(t.target)
t.target = 18
println(t.target)Đầu ra:
30
18Bên trong một phương thức truy cập, hãy dùng field, không dùng tên thuộc tính: viết target = value bên trong hàm setter của target sẽ gọi lại hàm setter mãi mãi:
var target = 20
set(value) {
// target = value // gọi lại setter này: đệ quy vô hạn
field = value // lưu giá trị
}Hàm setter cũng là nơi xử lý các thay đổi, chẳng hạn như đếm hoặc ghi lại chúng:
class Player(name: String) {
var changes = 0
private set
var name = name
set(value) {
field = value.trim()
changes++
}
}Bên trong main:
val p = Player("ada")
p.name = " Ada "
p.name = "Ada L."
println("${p.name} after ${p.changes} changes")Đầu ra:
Ada L. after 2 changesThử thách
DễHoàn thiện lớp Circle(radius: Double). radius là một var có bộ thiết lập lưu các giá trị âm thành 0. Thêm các thuộc tính chỉ đọc diameter và area (π r² với Math.PI) cùng bộ truy cập tùy chỉnh, và thuộc tính label, trả về r=2.0 d=4.0 a=12.57 với diện tích được làm tròn đến hai chữ số thập phân ("%.2f".format(area)).
Code được cung cấp đọc một bán kính trên mỗi dòng, in ra label, sau đó nhân đôi bán kính của hình tròn cuối cùng và in label lần nữa, vì vậy các giá trị phải thay đổi theo bán kính.
Code của bạn nằm trong Circle.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 xử lý đầu vào (input) và đầu ra (output) đã có sẵn: giữ nguyên.
val input = generateSequence(::readLine).toList()
var last = Circle(0.0)
for (line in input) {
last = Circle(line.toDouble())
println(last.label)
}
last.radius *= 2
println(last.label)
}
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