Swift 对象的初始化需要保证所有的非可选属性都被初始化。而初始化又分为 designated 和 convenience 两种。还有 required,required 可以和那两种方法进行组合。默认是非 required,designated
规则如下:
- designated 和 convenience 都可以有多个实现
- designated 初始化方法里必须保证的非可选属性都被初始化.
- 子类的 designated 初始化方法必须调用父类的 designated 初始化方法。而且对自己的独有的属性(非继承来的)的赋值语句必须写在调用父类的 designated 初始化方法之前,如果想更改父类初始化方法中的赋值,则可以在调用父类初始化方法之后,再次进行更改
- convenience 初始化方法必须调用自己的 designated 初始化方法
- extension 里不能有 designated 初始化方法
- 如果子类里有自己的初始化方法,则也必须重写父类 required 的初始化方法。允许把 required designated 重写成 designated convenience,当然反过来也可以
- 如果子类里重写了父类 required 的初始化方法,则不会继承父类其他的初始化方法
针对第 6,7 两点的例子如下:
1 | class Person { |
2 | var name : String |
3 | var age :Int |
4 | init(name: String, age: Int) { |
5 | self.name = name |
6 | self.age = age |
7 | } |
8 | required convenience init(name: String) { |
9 | self.init(name: name, age: 18) |
10 | } |
11 | } |
12 | class Student: Person { |
13 | var grades: [String] = [] |
14 | //把父类的required convenience重写成了required designated |
15 | required init(name: String) { |
16 | super.init(name: name, age: 18) |
17 | } |
18 | } |
19 | //编译不通过 错误信息:Extra argument 'age' in call |
20 | //说明没有继承父类其他的初始化方法 |
21 | let student = Student(name: "lkk", age: 22) |