Skip to Content

Access Control trong Swift

1. Giới thiệu

Access control giới hạn quyền truy cập vào code từ các phần khác của chương trình.

2. Các mức Access Control

MứcPhạm vi
openMọi nơi + có thể override/kế thừa
publicMọi nơi trong các modules
internalTrong cùng module (mặc định)
fileprivateTrong cùng file
privateTrong cùng scope (class/struct)

3. Private

class BankAccount { private var balance: Double = 0 private let accountNumber: String init(accountNumber: String) { self.accountNumber = accountNumber } func deposit(_ amount: Double) { if amount > 0 { balance += amount } } func withdraw(_ amount: Double) -> Bool { if amount > 0 && balance >= amount { balance -= amount return true } return false } func getBalance() -> Double { balance } } let account = BankAccount(accountNumber: "123456") account.deposit(1000) // account.balance = 0 // Error: 'balance' is private print(account.getBalance()) // 1000.0

4. Fileprivate

// Trong cùng file, có thể truy cập class DataManager { fileprivate var cache: [String: Any] = [:] fileprivate func clearCache() { cache.removeAll() } } class CacheHelper { let manager = DataManager() func reset() { // OK: cùng file manager.clearCache() manager.cache = [:] } }

5. Internal (Default)

// Không cần từ khóa - mặc định là internal struct User { var name: String // internal var email: String // internal func validate() { // internal // ... } } // Tường minh: internal struct Product { internal var price: Double }

6. Public và Open

// Trong framework/library // Public: có thể truy cập nhưng không override public class NetworkManager { public var baseURL: String public init(baseURL: String) { self.baseURL = baseURL } public func fetch(endpoint: String) { // ... } } // Open: có thể override trong module khác open class UIComponent { open func render() { print("Rendering...") } }

7. Private Set

struct Counter { // Đọc được từ ngoài, chỉ ghi được từ trong private(set) var count: Int = 0 mutating func increment() { count += 1 } mutating func reset() { count = 0 } } var counter = Counter() print(counter.count) // 0 - OK counter.increment() print(counter.count) // 1 - OK // counter.count = 100 // Error: setter is private

8. Access Control cho Types

// Struct/Class private struct InternalHelper { } public class PublicService { } // Enum public enum APIError: Error { case networkError case invalidData } // Protocol internal protocol DataSource { func loadData() }

9. Computed Properties

class User { private var _password: String = "" public var password: String { get { String(repeating: "*", count: _password.count) } set { _password = hashPassword(newValue) } } private func hashPassword(_ p: String) -> String { // Hashing logic p + "_hashed" } }

10. Best Practices

// ✅ Good: Encapsulation tốt class ShoppingCart { private var items: [CartItem] = [] var itemCount: Int { items.count } var total: Double { items.reduce(0) { $0 + $1.price } } func add(_ item: CartItem) { items.append(item) } func remove(at index: Int) { guard items.indices.contains(index) else { return } items.remove(at: index) } } // ❌ Bad: Expose implementation class BadCart { var items: [CartItem] = [] // Public - có thể modify trực tiếp }

11. Subclassing Access

public class Animal { private var internalState: Int = 0 fileprivate var sharedState: Int = 0 public func publicMethod() { } private func privateMethod() { } } // Trong cùng file class Dog: Animal { func test() { // self.internalState // Error: private self.sharedState = 1 // OK: fileprivate publicMethod() // OK // privateMethod() // Error: private } }

📝 Tóm tắt

  • private - chỉ trong scope hiện tại
  • fileprivate - trong cùng file
  • internal - trong cùng module (mặc định)
  • public - mọi nơi, không override
  • open - mọi nơi, có thể override
  • private(set) - đọc public, ghi private
Last updated on