1>构造过程定义
构造过程是使用类、结构体或枚举类型的实例之前的准备过程。在新实例可用前必须执行这个过程,具体操作包括设置实例中每个存储型属性的初始值和执行其他必须的设置或初始化工作。通过定义构造器(Initializers)来实现构造过程,这些构造器可以看做是用来创建特定类型新实例的特殊方法。与 Objective-C 中的构造器不同,Swift 的构造器无需返回值,它们的主要任务是保证新实例在第一次使用前完成正确的初始化。
2>构造器
构造器在创建某个特定类型的新实例时被调用。它的最简形式类似于一个不带任何参数的实例方法,以关键字init命名
init(){
}
3>参数的内部名称和外部名称
跟函数和方法参数相同,构造参数也拥有一个在构造器内部使用的参数名字和一个在调用构造器时使用的外部参数名字。然而,构造器并不像函数和方法那样在括号前有一个可辨别的名字。因此在调用构造器时,主要通过构造器中的参数名和类型来确定应该被调用的构造器。正因为参数如此重要,如果你在定义构造器时没有提供参数的外部名字,Swift 会为构造器的每个参数自动生成一个跟内部名字相同的外部名。
需要注意的是:如果不通过外部参数名字传值,你是没法调用这个构造器的。只要构造器定义了某个外部参数名,你就必须使用它,忽略它将导致编译错误,要避免这个错误你可以使用下划线 ( _ )来显式描述它的外部名,以此重写上面所说的默认行为。
4>构造过程中常量属性的修改
对于类的实例来说,它的常量属性只能在定义它的类的构造过程中修改;不能在子类中修改。
5>默认构造器
如果结构体或类的所有属性都有默认值,同时没有自定义的构造器,那么 Swift 会给这些结构体或类提供一个默认构造器(default initializers)。这个默认构造器将简单地创建一个所有属性值都设置为默认值的实例。
6>结构体的逐一成员构造器
如果结构体没有提供自定义的构造器,它们将自动获得一个逐一成员构造器,即使结构体的存储型属性没有默认值。逐一成员构造器是用来初始化结构体新实例里成员属性的快捷方法。我们在调用逐一成员构造器时,通过与成员属性名相同的参数名进行传值来完成对成员属性的初始赋值。
eg:struct Size {
var width =0.0, height =0.0
}
let twoByTwo =Size(width:2.0, height:2.0)
7>值类型的构造器代理
构造器可以通过调用其它构造器来完成实例的部分构造过程。这一过程称为构造器代理,它能减少多个构造器间的代码重复。
8>类的继承和构造过程
类里面的所有存储型属性——包括所有继承自父类的属性——都必须在构造过程中设置初始值。
指定构造器和便利构造器
指定构造器(designated initializers)是类中最主要的构造器。一个指定构造器将初始化类中提供的所有属性,并根据父类链往上调用父类的构造器来实现父类的初始化。
每一个类都必须拥有至少一个指定构造器。在某些情况下,许多类通过继承了父类中的指定构造器而满足了这个条件。
便利构造器(convenience initializers)是类中比较次要的、辅助型的构造器。你可以定义便利构造器来调用同一个类中的指定构造器,并为其参数提供默认值。你也可以定义便利构造器来创建一个特殊用途或特定输入值的实例。
遍历构造器就是在指定构造器前面加convenience,
eg: convenience init(){
statements
}
9>类的构造器代理规则
规则 1
指定构造器必须调用其直接父类的的指定构造器。
规则 2
便利构造器必须调用同一类中定义的其它构造器。
规则 3
便利构造器必须最终导致一个指定构造器被调用。
子类可以在初始化时修改继承来的变量属性,但是不能修改继承来的常量属性。
10>构造器的自动继承
规则 1
如果子类没有定义任何指定构造器,它将自动继承所有父类的指定构造器。
规则 2
如果子类提供了所有父类指定构造器的实现——无论是通过规则 1 继承过来的,还是提供了自定义实现——它将自动继承所有父类的便利构造器。
即使你在子类中添加了更多的便利构造器,这两条规则仍然适用
11>可失败构造器
如果一个类、结构体或枚举类型的对象,在构造过程中有可能失败,则为其定义一个可失败构造器。这里所指的“失败”是指,如给构造器传入无效的参数值,或缺少某种所需的外部资源,又或是不满足某种必要的条件等。
为了妥善处理这种构造过程中可能会失败的情况。你可以在一个类,结构体或是枚举类型的定义中,添加一个或多个可失败构造器。其语法为在init关键字后面添加问号(init?)。
12>必要构造器
在类的构造器前添加required修饰符表明所有该类的子类都必须实现该构造器:
class SomeClass{
required init() {
// 构造器的实现代码
}
}
在子类重写父类的必要构造器时,必须在子类的构造器前也添加required修饰符,表明该构造器要求也应用于继承链后面的子类。在重写父类中必要的指定构造器时,不需要添加override修饰符:
class SomeSubclass:SomeClass{
required init() {
// 构造器的实现代码
}
}