Kiểm soát quyền truy cập
Thuộc phần Lập trình hướng đối tượng trong hành trình Swift của Coddy. Bài học 17 trên 57.
Tính đóng gói nghĩa là một kiểu kiểm soát cách sử dụng dữ liệu của nó. Quyền truy cập quyết định ai có thể xem một thuộc tính hoặc phương thức. Đánh dấu một thành viên là private sẽ ẩn thành viên đó khỏi toàn bộ code bên ngoài kiểu (và các phần mở rộng của kiểu đó trong cùng một tệp):
struct Account {
private var balance = 0
mutating func deposit(_ amount: Int) {
balance += amount
}
}
var a = Account()
a.deposit(50)
// a.balance = 1_000_000 // lỗi: không thể truy cập 'balance' do mức bảo vệ 'private'Mã bên ngoài chỉ có thể dùng những gì kiểu dữ liệu cung cấp. Kiểu dữ liệu có thể kiểm tra mọi thay đổi, nhờ vậy dữ liệu của nó không bao giờ rơi vào trạng thái mà kiểu dữ liệu không cho phép:
struct Account {
private var balance = 0
mutating func deposit(_ amount: Int) {
if amount > 0 { balance += amount }
}
func report() -> String {
"balance: \(balance)"
}
}
var a = Account()
a.deposit(50)
a.deposit(-999)
print(a.report())Đầu ra:
balance: 50Swift có năm mức truy cập. Nếu không có từ khóa, một thành viên có mức truy cập internal: hiển thị ở mọi nơi trong cùng một module (ứng dụng hoặc package của bạn). Các mức từ mở nhất đến hạn chế nhất:
open // các module khác có thể sử dụng và tạo lớp con từ đó (chỉ áp dụng cho lớp)
public // các module khác có thể sử dụng
internal // mặc định: toàn bộ module
fileprivate // chỉ trong tệp mã nguồn này
private // chỉ trong kiểu này (và các phần mở rộng của kiểu đó trong tệp)Các phương thức trợ giúp riêng tư giúp giao diện công khai gọn nhẹ: bên gọi biết kiểu dữ liệu làm gì, chứ không phải cách nó hoạt động.
struct Password {
private let text: String
init(_ text: String) { self.text = text }
var isStrong: Bool {
hasDigit() && text.count >= 8
}
private func hasDigit() -> Bool {
text.contains { $0.isNumber }
}
}
print(Password("secret123").isStrong)
print(Password("short1").isStrong)Đầu ra:
true
falseThử thách
DễHoàn thiện struct Locker. code và items là private. store(_:code:) chỉ thêm một món đồ khi mã khớp và trả về kết quả cho biết việc thêm có thành công hay không; items(code:) trả về các món đồ đã lưu, nối bằng , (hoặc empty) khi mã khớp, còn không thì trả về wrong code.
Code được cung cấp đọc mã của tủ khóa, sau đó đọc các lệnh put <code> <item> hoặc open <code>. Với mỗi lệnh put, chương trình in ra stored hoặc denied, còn với mỗi lệnh open, chương trình in ra kết quả tương ứng.
Đặt code của bạn trong Locker.swift. main.swift 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ử
// Đoạn code đầu vào/đầu ra có sẵn: giữ nguyên
var input: [String] = []
while let line = readLine() { input.append(line) }
var locker = Locker(code: input[0])
for cmd in input.dropFirst() {
let p = cmd.split(separator: " ").map(String.init)
if p[0] == "put" {
print(locker.store(p[2], code: p[1]) ? "stored" : "denied")
} else {
print(locker.items(code: 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ớpPhương thức và selfHàm khởi tạoLớp là tham chiếuÔn tập: Thẻ thư viện4Đóng gói
Kiểm soát quyền truy cậpChỉ đọc từ bên ngoàiBảo vệ trạng tháiHàm khởi tạo có thể thất bạiÔn tập: Tài khoản ngân hàng2Struct và kiểu giá trị
StructNgữ nghĩa giá trịPhương thức thay đổiStruct hay classÔn tập: mặt hàng trong kho5Kế thừa
Lớp conGhi đè phương thứcHàm khởi tạo và superfinal và hệ phân cấpÔn tập: hệ phân cấp nhân viên8Các giao thức tiêu chuẩn
CustomStringConvertibleEquatableComparableHashableÔn tập: Sắp xếp tùy chỉnhTự luyện tập: Playground Swift