Bộ sửa đổi phạm vi truy cập
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 8 trên 57.
Tính đóng gói nghĩa là một lớp kiểm soát cách dữ liệu của nó được sử dụng. Các từ bổ nghĩa về phạm vi hiển thị quyết định ai có thể xem một thành viên. private ẩn thành viên đó khỏi mọi thứ bên ngoài lớp, vì vậy chỉ các phương thức của chính lớp mới có thể truy cập:
class Account {
private var balance = 0
fun deposit(amount: Int) {
if (amount > 0) balance += amount
}
fun report() = "balance: $balance"
}Bên trong main:
val a = Account()
a.deposit(50)
a.deposit(-999)
println(a.report())
// a.balance = 1_000_000 // lỗi: không thể truy cập 'balance' vì thuộc tính này là privateĐầu ra:
balance: 50Kotlin có bốn từ bổ nghĩa. Nếu không có từ bổ nghĩa nào, khai báo sẽ là public, hiển thị ở mọi nơi:
public // Mặc định: có thể truy cập ở mọi nơi
internal // Có thể truy cập trong cùng module (ứng dụng hoặc thư viện)
protected // Có thể truy cập trong lớp và các lớp con
private // Có thể truy cập bên trong lớp (hoặc tệp, đối với các khai báo ở cấp cao nhất)Các hàm trợ giúp riêng tư giúp giữ bề mặt công khai nhỏ gọn. Người gọi chỉ thấy lớp làm gì, chứ không thấy cách lớp thực hiện:
class Password(private val text: String) {
val isStrong: Boolean
get() = hasDigit() && text.length >= 8
private fun hasDigit() = text.any { it.isDigit() }
}Bên trong main:
println(Password("secret123").isStrong)
println(Password("short1").isStrong)Đầu ra:
true
falseCác thuộc tính trong hàm khởi tạo cũng có thể dùng từ bổ nghĩa: private val lưu một giá trị mà code bên ngoài không thể đọc. Việc ẩn dữ liệu giúp lớp kiểm tra mọi thay đổi và giữ các quy tắc của mình:
class Locker(private val code: String) {
private val items = mutableListOf<String>()
fun store(item: String, code: String): Boolean {
if (code != this.code) return false
items.add(item)
return true
}
}Thử thách
DễHoàn thiện lớp (class) Locker(private val code: String). Danh sách items là riêng tư. store(item, code) chỉ thêm phần tử khi code trùng khớp và trả về kết quả cho biết thao tác đó có thành công hay không; open(code) trả về các phần tử được nối bằng , (hoặc empty) khi code trùng khớp, nếu không thì trả về wrong code.
Đoạn code được cung cấp đọc code của tủ khóa, sau đó đọc các lệnh put <code> <item> hoặc open <code>. Đoạn code in ra stored hoặc denied cho mỗi lệnh put, và in ra kết quả của mỗi lệnh open.
Code của bạn cần nằm trong Locker.kt. Main.kt chứa đoạn 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 locker = Locker(input[0])
for (cmd in input.drop(1)) {
val p = cmd.split(" ")
if (p[0] == "put") println(if (locker.store(p[2], p[1])) "stored" else "denied")
else println(locker.open(p[1]))
}
}
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