Tags: Swift 学习笔记
发布时间:2015-08-04
修改时间:2015-08-04
作者:Erwin
博客地址:技术杂货铺
欢迎转载,转载请注明出处。
Swift学习笔记系列——(13)初始化
初始化
目标:类、结构体和枚举
目的:实例使用前的准备,存储属性赋值以及其他必要操作
给存储属性初始值
类和结构体的存储属性在使用前必须要有初始值,提供初始值可以通过定义时指定,也可以通过构造方法赋值。
初始化过程中给存储属性赋值,不会触发观察者行为。
自定义初始化
通过构造方法的参数给必须要有值的存储属性赋值、给可选类型属性赋值;
初始化过程中给常量属性赋值;
构造方法的参数语法和函数以及方法的相同。
在初始化阶段中的任意时刻,都可以给常量属性赋值,但是一旦赋值就不能修改了。
默认构造方法
如果结构体和类中所有的属性都有默认值了,尽管没有明确声明,但实际上已经有了一个不需要参数的默认构造方法。
结构体的额外特权(Memberwise Initializers for Structure Types)
即使没有给全部属性度提供默认值,结构体仍会自动获得一个构造方法(Memberwise Initializers)。
这个构造方法以结构体成员名字作参数,会给其中的成员赋值。
值类型的初始化代理
构造方法可以调用其它构造方法来实现一个实例初始化的一部分。这个过程,叫做构造方法代理(initializer delegation),这样做避免了在多个构造方法中出现重复代码。
构造方法代理的工作规则和什么形式的代理是被允许的,这些对于值类型和类类型而言是不相同的。
对于值类型,采用selft.init引用其他构造方法即可。
需要注意如果值类型定义了构造方法,就不能再访问它的默认构造方法了(或者Memberwise Initializers,当值类型是结构体的时候)。这是为了避免意外使用默认构造方法,而没有使用提供了必要操作的稍微复杂的自定义构造方法。
对于值类型,如果想在自定义的构造方法中引用自动获得的构造方法,那么把自定义构造方法写在扩展中。
类的继承和初始化
继承是类的特有行为,类的初始化要保证类的所有属性都被赋值,不论是继承来的还是自身定义的。
指定构造方法
必须要有,可以有多个,但一般是一个,是继承链上的一部分,子类的指定构造方法会调用超类的构造方法。
方便构造方法
不是必须的,必须要引用同一个类的指定构造方法,可以有多个。定义的时候需要用关键字“convenience ”特别强调。
构造方法调用其他构造方法的规则
指定构造方法必须调用它的直接超类的一个指定构造方法。
方便方法必须调用同一个类的另外一个构造方法。
方便方法必须最终调用到一个指定构造方法。
初始化的两个阶段
这部分主要要说明类的初始化顺序。
顺序是这样的:
https://www.processon.com/view/link/55bb389be4b0f902d22391f7
第二阶段开始才可以访问实例方法和self。
构造方法的继承和重写
子类不默认继承超类的构造方法。
子类用override关键字定义重写的构造方法。
根据类构造方法引用的规则,子类不可能重写超类的方便构造方法,只能重写超类的指定构造方法。
构造方法自动继承
子类新加的属性都有默认值的前提下:
如果子类没有定义任何指定构造方法,则默认继承超类的指定构造方法。
如果子类有超类所有指定构造方法的实现,无论是通过继承还是通过重写,那么子类会默认继承超类的全部方便构造方法。
可失败构造方法
init?
不能定义拥有相同参数类型和名称的可以失败的和不可失败的构造方法。
枚举
可以定义失败的构造方法,根据参数选择是否能构造出一个成员。
enum TemperatureUnit { case Kelvin,Celsius,Fahrenheit init?(symbol: Character) { switch symbol { case "K": self = .Kelvin case "C": self = .Celsius case "F": self = .Fahrenheit default: return nil } } }
枚举自动获得的可以失败构造方法
获得条件:枚举成员有原始值
形式:init?(rawValue:)
类的可以失败的构造方法
值类型的可失败构造方法可以在构造方法的任意时刻出发构造失败,但是对于类就不行了。类的构造方法要出发构造失败,需要在自身的所有存储属性被赋值了初始值而且调用了其他构造方法之后才能进行。
可以失败构造方法的传递
可以失败构造方法可以调用不可失败构造方法,但这样会导致构造结果的不确定性。
不可失败构造方法不可以调用可以失败构造方法。因为这样构造结果的确定性就未知了。
继承链上的构造方法失败后,后续初始化操作不再继续执行。
重写可以失败的构造方法
可失败的构造方法可以被重写为不可失败的构造方法,但不能再引用超类的可失败构造方法了。
不可失败的构造方法不可以被重写为可失败的构造方法。
init!可失败构造方法
init!和init?可以相互调用,相互重写。
必须构造方法
required修饰符标记的构造方法叫必须构造方法,所有子类必须要有。
必须构造方法有传递性,子类的子类也要有。
通过继承就获得了的,不必提供实现。
重写了一个必须构造方法,不必用override关键字,只用required关键字就行了。
通过闭包和函数给属性设置默认值
可以用闭包和函数给属性设置默认值
用闭包给属性设置值的时候要注意,此时初始化尚未完成,不能访问实例属性和self。
几种构造方法释义
分类依据 | 名称 | 标记和说明 |
是否在继承链上 | 指定构造方法 | |
方便构造方法 | convenience | |
是否构造成功 | 不可失败构造方法 | |
可失败构造方法 | init?或者init! | |
子类是否构一定要实现 | 一般构造方法 | |
必须构造方法 | required | |
子类是否构重写 | 一般构造方法 | |
重写构造方法 | override | |
自动获得的构造方法 | 类和结构体的无参数构造方法 | 条件:属性都有默认值而且没有定义构造方法 |
结构体的初始化成员构造方法 | 条件:没有定义构造方法 | |
枚举自动获得的可失败构造方法 | init?(rawValue:) | |
类自动继承的指定构造方法 | 条件:新加属性有默认值而且没有定义指定构造方法 | |
类自动继承超类所有方便构造方法 | 条件:新加属性有默认值而且有超类所有的指定构造方法实现 |