swift中强化了designated 初始化方法的地位。在子类中也强制(显示或隐式的)调用 super 版本的 designated 初始化,所以无论怎样被初始化的对象总是可以完成完整的初始化的。
class ClassB: ClassA {
let numB: Int
override init(num: Int) {
numB = num + 1
super.init(num: num)
}
}
注意:在 init 里我们可以对 let 的实例常量进行赋值,这是初始化方法的重要特点。正常情况下 let 声明的值是不可变的,无法被赋值,这对构建线程安全的 API 十分有用。而 init 只可能被调用一次,所以在 init 里我们可以为不变量进行赋值,而不会引起任何线程安全的问题
required关键字
designated初始化方法是来保证该类对象能被完整初始化的,如果designated init方法有required修饰,就表示子类一定要实现该init方法。这样做的好处是可以保证依赖于某个 designated 初始化方法的 convenience 一直可以被使用。
即:required修饰init方法, 强制子类重写该方法。
class ClassBBB: ClassAAA {
let numB: Int
required init(num: Int) {
numB = num + 1
super.init(num: num)
}
}
convenience关键字
和required一样的是,convenience也是用来修饰init方法的,作用是增加便捷的init方法。但是有几点需要注意:
convenience init方法必须调用本类中 的designated初始化方法完成初始化设置。
convenience的初始化方法不能被子类重写或者是从子类中以super的方式被调用
class ClassAA {
let numA: Int
init(num: Int) {
numA = num
}
convenience init(bigNum: Bool) {
self.init(num: bigNum ? 10000 : 1) // 所有的 convenience 初始化方法都必须调用同一个类中的 designated 初始化完成设置
}
}
class ClassBB: ClassAA {
let numB: Int
override init(num: Int) {
numB = num + 1
super.init(num: num)
}
}
只要在子类中实现重写了父类 convenience 方法所需要的 init 方法的话,我们在子类中就可以使用父类的 convenience 初始化方法了。
convenience 和 required关键字可以同时使用
同时使用这两个关键字,确保子类对其进行实现。