给存储属性设定初值
- 在初始化器中设置。
- 在属性定义中提供默认值。
自定义初始化器
自动为参数提供外部参数名(和内部参数名一样),如果自己没有提供的话。
如果不想使用外部参数名,用 _
占位。(和方法类似)
可选类型的属性,如果没有手动设定初值(通过初始化器,或者提供默认值),会默认为 nil
。
在初始化器中,可以修改非继承而来(言外之意是,继承而来的不可以)的常量属性。
默认初始化器
如果一个结构或者基类(言外之意是,子类不可以)的属性都有默认值,
那么 Swift 会自动提供一个默认的初始化器。
结构还自动拥有一个 memberwise 初始化器,即使其属性没有默认值。
但如果为结构这样的值类型提供了自定义初始化器,那默认初始化器和 memberwise 初始化器都不会存在。
如果想让两者共存,可以把自定义初始化器放在 扩展 中,或者自己手动实现...
类的继承与初始化
指定的初始化器,便利的初始化器(用 convenience
前缀)。
初始化链:
- 指定的初始化器一定向上调用超类的指定的初始化器。
- 便利的初始化器一定调用同一个类中的其他初始化器。
- 便利的初始化器最终会调用一个指定的初始化器。
双重初始化
- 由下向上。
- 由上及下。
安全检查:
- 指定的初始化器必须保证,在自己这个类中引入的属性都被初始化,然后才能向上委托给超类。
- 指定的初始化器必须保证,在向上委托给超类之前,不给继承而来的属性赋值。否则,该赋值将被重写。
- 便利的初始化器必须保证,在委托给其他初始化器之前,不给任意一个属性赋值。否则,该赋值将被重写。
- 在第一重初始化结束之前,初始化器不能调用实例方法,不能读取任意一个属性的值,不能引用
self
为一个值。
只有在第一重初始化结束后,实例才是有效的。这时,属性可以访问,方法可以调用。
初始化器的继承与重写
默认情况下,子类不继承超类的初始化器,防止超类初始化器调用导致子类的不完全初始化。
当子类提供了和超类一样的初始化器,那就是在重写它,需要前缀 override
。
初始化器的自动继承
子类中,如果所有新的属性都有默认值的话,那么,满足下面两个规则会被应用:
- 如果子类没有定义指定的初始化器,那么,会自动继承超类的所有的指定的初始化器。
- 如果子类提供了超类所有的指定初始化器(无论通过规则1,还是提供了自定义的实现),
那么,会自动继承超类的所有的便利的初始化器。
Required 初始化器
required
表征,该初始化器必须在所有子类中实现,而且,在子类实现中,也需标明 required
。