HoRain 云小助手个人主页⛺️生活的理想就是为了理想的生活!⛳️ 推荐前些天发现了一个超棒的服务器购买网站性价比超高大内存超划算忍不住分享一下给大家。点击跳转到网站。目录⛳️ 推荐Swift 访问控制访问级别概览访问级别详解1. open和 public2. internal默认级别3. fileprivate4. private访问控制规则1. 单一实体原则2. 默认构造器的访问级别3. 结构体成员初始化协议访问控制1. 协议本身的访问控制2. 协议要求的访问控制3. 协议继承扩展的访问控制1. 扩展的默认访问级别2. 为扩展指定访问级别泛型访问控制类型别名访问控制嵌套类型访问控制实用示例示例1封装实现细节示例2模块化设计示例3测试友好的设计访问控制的最佳实践注意事项Swift 访问控制Swift 的访问控制机制用于限制代码中实体类、结构体、枚举、属性、方法、初始化器等的访问级别实现封装和信息隐藏。访问级别概览Swift 提供了5个不同的访问级别从高到低访问级别描述适用场景open​最高访问级别可被任何源文件访问、继承、重写框架的公共接口public​可被任何源文件访问但模块外不能继承和重写模块的公共APIinternal​默认级别只能被同一模块内的源文件访问模块内部实现fileprivate​只能被当前源文件访问同一文件内的工具函数private​最低级别只能在当前作用域及其扩展中访问类/结构体内部细节访问级别详解1.open和public// 定义在框架中 public class PublicClass { public var publicProperty 0 internal var internalProperty 1 fileprivate var fileprivateProperty 2 private var privateProperty 3 public init() {} } // 只能在模块内继承 class SubPublicClass: PublicClass { override init() { super.init() print(publicProperty) // ✅ print(internalProperty) // ✅ // print(fileprivateProperty) // ❌ 错误 // print(privateProperty) // ❌ 错误 } } // 定义在框架中 open class OpenClass { public var publicProperty 0 open var openProperty 1 // 可重写 public init() {} } // 在另一个模块中 class SubOpenClass: OpenClass { // ✅ open允许跨模块继承 override init() { super.init() print(publicProperty) // ✅ print(openProperty) // ✅ } // 可以重写open属性和方法 override var openProperty: Int { get { return 10 } set {} } }2.internal默认级别// 不指定访问级别时默认为internal struct InternalStruct { // 隐式internal var property 0 // 隐式internal func doSomething() { // 隐式internal print(内部方法) } } // 同一模块内的任何源文件都可以访问 let obj InternalStruct() // ✅ obj.property 10 // ✅ obj.doSomething() // ✅3.fileprivate// FileA.swift fileprivate class FilePrivateClass { fileprivate var fileprivateVar 0 private var privateVar 1 func test() { print(fileprivateVar) // ✅ print(privateVar) // ✅ } } // 同一文件内可访问 let instance FilePrivateClass() // ✅ instance.fileprivateVar 5 // ✅ // instance.privateVar 10 // ❌ 错误 // FileB.swift // 不同文件无法访问 // let instance2 FilePrivateClass() // ❌ 错误4.privateclass BankAccount { private var balance: Double 0.0 private(set) var accountNumber: String // 公开获取私有设置 init(accountNumber: String) { self.accountNumber accountNumber } public func deposit(amount: Double) { balance amount } public func withdraw(amount: Double) - Bool { if balance amount { balance - amount return true } return false } public func getBalance() - Double { return balance } } let account BankAccount(accountNumber: 12345) account.deposit(amount: 1000) print(account.accountNumber) // ✅ // account.accountNumber 67890 // ❌ 错误 // print(account.balance) // ❌ 错误访问控制规则1. 单一实体原则每个实体的访问级别不能高于其依赖实体的访问级别。// 错误示例 private class PrivateClass {} // public var publicVar: PrivateClass? // ❌ 错误使用private类型的public属性 // 正确示例 public class PublicClass {} private var privateVar: PublicClass? // ✅2. 默认构造器的访问级别默认构造器的访问级别与所属类型的访问级别相同除非类型是public。public class PublicClass2 { var x: Int public init() { x 0 } // 必须显式声明为public } internal class InternalClass { var x: Int // 默认init是internal }3. 结构体成员初始化结构体默认成员初始化器的访问级别受其成员属性访问级别的影响。private struct PrivateStruct { var a: Int var b: Int // 默认成员构造器是private } internal struct InternalStruct2 { public var a: Int internal var b: Int // 默认成员构造器是internal }协议访问控制1. 协议本身的访问控制public protocol PublicProtocol { var publicProperty: Int { get set } func publicMethod() } internal protocol InternalProtocol { var internalProperty: String { get } }2. 协议要求的访问控制public protocol Drawable { func draw() // 隐式public // 可以限制协议要求的访问级别 internal func internalDraw() }3. 协议继承public protocol RefinedProtocol: InternalProtocol { // 继承的协议不能比当前协议访问级别高 func additionalMethod() }扩展的访问控制1. 扩展的默认访问级别public class SomeClass { private var secret secret } extension SomeClass { // 扩展中的成员默认internal func internalMethod() { print(secret) // ✅ 可以访问原类型的private成员 } }2. 为扩展指定访问级别public extension SomeClass { // 显式指定为public public func publicMethod() { // 可以添加新功能 } } private extension SomeClass { // 只能在同一文件内访问 func privateMethod() { print(secret) // ✅ } }泛型访问控制// 泛型类型的访问级别 public struct StackElement { private var items [Element]() public mutating func push(_ item: Element) { items.append(item) } public mutating func pop() - Element? { return items.popLast() } } // 泛型函数的访问级别 public func swapTwoValuesT(_ a: inout T, _ b: inout T) { let temporaryA a a b b temporaryA }类型别名访问控制// 类型别名的访问级别可以低于或等于原类型 private class PrivateClass2 {} typealias Alias PrivateClass2 // ✅ 可以更严格 public class PublicClass3 {} // typealias PrivateAlias PublicClass3 // ❌ 不能更严格嵌套类型访问控制public class OuterClass { public class NestedPublicClass { public func publicMethod() {} } internal class NestedInternalClass { func internalMethod() {} } private class NestedPrivateClass { private func privateMethod() {} } } let nested OuterClass.NestedPublicClass() // ✅ // let privateNested OuterClass.NestedPrivateClass() // ❌实用示例示例1封装实现细节public struct Temperature { private var celsius: Double public var fahrenheit: Double { get { return celsius * 9/5 32 } set { celsius (newValue - 32) * 5/9 } } public var kelvin: Double { get { return celsius 273.15 } set { celsius newValue - 273.15 } } public init(celsius: Double) { self.celsius celsius } public init(fahrenheit: Double) { celsius (fahrenheit - 32) * 5/9 } } let temp Temperature(celsius: 0) print(temp.fahrenheit) // 32.0 // temp.celsius 10 // ❌ 错误celsius是私有的示例2模块化设计// NetworkModule public protocol NetworkService { func fetchData(from url: String) - Data } internal class NetworkServiceImpl: NetworkService { internal init() {} public func fetchData(from url: String) - Data { // 实现网络请求 return Data() } } // 工厂方法 public class NetworkServiceFactory { public static func makeService() - NetworkService { return NetworkServiceImpl() // 内部实现外部只知道协议 } } // 客户端代码 let service NetworkServiceFactory.makeService() // 类型是NetworkService let data service.fetchData(from: https://api.example.com)示例3测试友好的设计public class DataProcessor { private let data: [Int] public init(data: [Int]) { self.data data } public func process() - Int { return data.reduce(0, ) } // 为测试提供的内部方法 internal func validateData() - Bool { return !data.isEmpty data.allSatisfy { $0 0 } } } // 单元测试中 import XCTest testable import MyModule // 使用testable可以访问internal成员 class DataProcessorTests: XCTestCase { func testDataValidation() { let processor DataProcessor(data: [1, 2, 3]) XCTAssertTrue(processor.validateData()) // ✅ 可以访问internal方法 } }访问控制的最佳实践最小化暴露原则默认使用private或fileprivate只在必要时提升访问级别协议导向编程通过协议暴露接口而非具体实现使用协议组合代替继承测试友好设计使用testable import进行单元测试为测试设计适当的访问级别框架设计公共API使用open和public内部实现使用internal细节使用private和fileprivate模块化设计合理划分模块边界明确模块间的依赖关系通过访问控制减少耦合注意事项枚举public enum CompassPoint { case north, south, east, west // 枚举成员的访问级别自动与枚举相同 }Getter 和 Setterpublic struct TrackedString { public private(set) var numberOfEdits 0 public var value: String { didSet { numberOfEdits 1 } } public init() {} } var string TrackedString() string.value Hello print(string.numberOfEdits) // 1 // string.numberOfEdits 0 // ❌ 错误setter是private子类子类的访问级别不能高于父类重写的方法访问级别可以高于父类方法Swift 的访问控制机制提供了强大的封装能力帮助开发者构建模块化、可维护、安全的代码。合理使用访问控制可以提高代码质量减少错误并支持更好的团队协作。❤️❤️❤️本人水平有限如有纰漏欢迎各位大佬评论批评指正如果觉得这篇文对你有帮助的话也请给个点赞、收藏下吧非常感谢! Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧