构造器会为程序中的类、结构体或枚举引入构造器。构造器使用关键字init来声明,有两种基本的形式。结构体、枚举、类可以有任意数量的构造器,但是类的构造器具有不同的规则和行为。不同于结构体和枚举,类有两种构造器,即指定构造器和便利构造器。
采用如下形式声明结构体和枚举的构造器,以及类的指定构造器:
init(参数列表){
}
类的指定构造器直接将类的所有属性初始化。它不能调用类中的其他构造器,如果类有超类,则必须调用超类的一个指定构造器。如果该类从它的超类继承了属性,必须在调用超类的指定构造器后才能修改这些属性。
指定构造器只能在类声明中声明,不能在扩展声明中声明
结构体和枚举的构造器可以调用其他已声明的构造器,从而委托其他构造器来进行部分或者全部的构造过程。
要为类声明一个便利构造器,用convenience 声明修饰符来标记构造器声明:
convenience init(参数列表){
<!--构造语句-->
}
便利构造器可以将构造过程委托给另一个便利构造器或一个指定构造器。但是,类的构造过程,必须以一个将类中所有属性完全初始化的指定构造器的调用作为结束。便利构造器不能调用超类的构造器。
可以使用required声明修饰符,将便利构造器和指定构造器标记为每个子类都必须实现的构造器。这种构造器的子类实现也必须使用required 声明修饰符标记。
默认情况下,超类中的构造器不会被子类继承。但是,如果子类的所有存储属性都有默认值,而且子类自身没有定义任何构造器,它将继承超类的构造器。如果子类重写了超类的所有指定构造器,子类将继承超类的所有便利构造器。
和方法、属性和下标一样,需要使用override 声明修饰符标记重写的指定构造器。
注意
如果使用required 声明修饰符标记一个构造器,在子类中重写这种构造器时,无需使用override修饰符。
就像函数和方法,构造器也可以抛出或者重抛错误,你可以在构造器参数列表的圆括号之后使用throw 或rethrows 关键字来表明相应的抛出行为。
可失败构造器
可失败构造器可以生成所属类型的可选实例或者隐式解包可选实例。因此,这种构造器通过返回nil来指明构造过程失败。
声明生成可选实例的可失败构造器时,在构造器声明的init关键字后追加一个问号(init?)。声明生成隐式解包可选实例的可失败构造器时,在构造器声明后追加一个叹号(init!)。使用init?可失败构造器生成结构体的一个可选实例的例子如下。
struct SomeStruct{
let string:String
//生成一个SomeStruct的可选实例
init?(input:String){
if input.isEmpty{
//丢弃self,并返回nil
return nil
}
string = input
}
}
调用init?可失败构造器和调用非可失败构造器的方式相同,不过需要处理可选类型的返回值。
if let actualInstance = SomeStruct(input:"Hello") {
//利用SomeStruct 实例做些事情
}else{
//SomeStruct 实例的构造过程失败,构造器返回了nil
}
可失败构造器可以在构造器实现中的任意位置返回nil。
可失败构造器可以委托任意种类的构造器。非可失败可以委托其他非可失败构造器构造器或者init!可失败构造器。非可失败构造器可以委托超类的init?可失败指定构造器,但是需要使用强制解包,例如 super.init()!。
构造过程失败通过构造器委托来传递。具体来说,如果可失败构造器委托的可失败构造器构造过程失败,并返回nil,那么该可失败构造器也会构造失败并隐式的返回nil。如果非可失败构造器委托的init?可失败构造器构造失败并返回了nil,那么会发生运行时错误(如同使用!操作符去强制解包一个值为nil的可选值)。
子类可以用任意种类的指定构造器重写超类的可失败构造器。但是只能用非可失败指定构造器重写超类的非可失败指定构造器。
网友评论