初始化器
类、结构体、枚举都可以定义初始化器,结构体自带初始化器,枚举可以通过rawValue定义原始值,也可以通过枚举直接点语法,重点就是看类的初始化器。
类有两种初始化器,指定初始化器和便捷初始化器。
指定初始化器
任何一个类都必须有一个指定初始化器,如果你不写,系统会默认给你生成一个init初始化器,但是如果你自定义了初始化器,那么这个初始化器就不存在了。指定初始化器不建议多写,一两个足够了。
子类指定初始化器必须调用直系父类的指定初始化器
同一个类的指定初始化器无法调用本身的指定初始化器。
便捷初始化器
便捷初始化器必须调用一个指定初始化器。
初始化流程
首先调用本类的初始化器,为所有的存储属性赋值,如果有父类,那么再调用父类的指定初始化器初始化,一直到他没有父类为止,其次,保证所有的本类和父类存储属性都有值以后,可以重新修改存储属性或者做一些方法的操作(self才可以使用,不过现在好像放开了) 所有的这些都是为了保证存储属性有值,也是做到了swift的安全。
**class** Person {
**var** age = 0
**init**(age:Int) {
**self**.age = age
}
}
**class** Student : Person {
**var** score = 0
**convenience** **init**(score:Int) {
**self**.init(score: 100, age: 10)
}
**init**(score:Int,age:Int) {
**super**.init(age: age)
**self**.score = score
}
}
子类的任何初始化器都可以重写父类的指定初始化器,但是不能重写父类的便捷初始化器,便捷初始化器永远是横向调用,即本类调用,只有指定初始化器可以调用父类的指定初始化器,调用父类的便捷初始化器无效。
自动继承
如果子类没有写任何初始化器,那么会默认继承父类的指定初始化器。
如果子类写了指定初始化器,那么父类的指定初始化器无效。
如果子类继承了所有父类的指定初始化器(要么什么都不写,要么全部重写)那么也可以使用所有父类的便捷初始化器。
required关键字
如果父类的指定初始化器有require修饰,且子类自定义初始化器,那么必须要重写父类的require初始化器,并且可以不用写override。
在本类中调用本类中的存储属性赋值不会触发属性观察器,但是在子类中赋值会触发父类的指定初始化器。
可失败初始化器
init?(name:String){
if name.isEmpty {
return nil
}
self.name = name
}
可以通过?或者!标记是可失败初始化器,在某些情况下,包括枚举的原始值初始化或者一些数字字符串强转的系统方法,都是通过可失败初始化器来辨别特殊情况的参数错误。可失败初始化器可以调用非可失败初始化器。
非可失败初始化器调用可失败初始化器需要强制解包,或者可失败初始化器声明的时候就用!修饰解包。
init?(name:String){
if name.isEmpty {
return** nil
}
self.name = name
}
convenience init(){
self.init(name: "")!
}
// 或者用下面这种方式
init!(name:String){
if name.isEmpty {
return** nil
}
self.name = name
}
convenience init(){
self.init(name: "")
}
可失败不能重写非可失败初始化器,非可失败可以重写可失败初始化器。