swift 中没有 new 关键字,对象创建通过初始化器完成;私有属性必须在实例完全初始化前赋值,可在声明时设默认值或在 init 中显式赋值,子类不可直接访问父类私有属性。

私有属性在初始化时和其他属性一样必须赋初值
Swift 要求所有存储属性(无论访问控制级别是 public、internal 还是 private)在实例完全初始化前都有确定值。这与访问权限无关,而是类型安全的硬性要求。
- 可以在属性声明时直接提供默认值:
private var id = UUID() - 也可以在
init中显式赋值:self.id = UUID() - 若属性是非可选且无默认值,又未在
init中初始化,编译器会报错
私有属性可在指定初始化器中自由访问和设置
只要初始化器定义在同一个类型内部(即属于该类/结构体),就能直接读写所有私有属性,无需额外语法或绕过机制。
- 例如:
private let creationDate: Date可在init()中用self.creationDate = Date()初始化 - 即使属性是
let常量,只要在第一阶段初始化完成前赋值,就合法
便捷初始化器也能初始化私有属性,但需遵守调用链规则
使用 convenience init 时,不能直接为属性赋值,而必须先调用同一类型的其他初始化器(最终抵达指定初始化器)。私有属性的初始化仍发生在指定初始化器中。
- 错误写法:
convenience init() { self.privateValue = 42 }→ 编译失败 - 正确写法:
convenience init() { self.init(value: 42) },再由指定初始化器完成赋值
子类无法直接访问父类的私有属性,但可通过开放接口间接初始化
如果父类有 private 属性,子类继承时不可见,也不能在子类初始化器中直接赋值。此时应:
- 将必要属性改为
fileprivate或internal(若设计允许) - 或由父类提供带参数的指定初始化器,让子类通过参数传递初始值
- 避免在子类中尝试“绕过”私有封装,这违背 Swift 封装原则











