swift构造器

 类和结构体的构造器
 1、在构造器内所有属性必须设置初始值(可选属性除外,因为可选属性初始值默认为nil),或者在属性声明时为其设置默认值也可以。
 2、在构造器内部设置初始值,是直接设置的,不会触发属性观察者。
 3、可以在构造器内部给常量(let修饰的)属性赋值,只要在构造过程结束时它设置成确定的值。一旦常量属性被赋值,它将永远不可更改,也不能在子类中修改。
 
 
 
 自定义构造器:
 1、实参标签 和 形参命名
 如 init(fromFahrenheit fahrenheit: Double) {
    
 }
 fromFahrenheit 是 实参标签;fahrenheit 是 形参命名
 
 如果在定义构造器时没有提供 实参标签,Swift 会为构造器的每个形参自动生成一个实参标签。
 
 如果不希望构造器的某个形参使用实参标签,可以使用下划线(_)来代替显式的实参标签来重写默认行为。
 如 init(_ celsius: Double){
    
 }
 
 
 默认构造器:
 1、如果结构体或类为所有属性提供了默认值,又没有提供任何自定义的构造器,那么 Swift 会给这些结构体或类提供一个默认构造器。
 
 
 
 结构体的逐一成员构造器:
 1、结构体如果没有定义任何自定义构造器,它们将自动获得一个逐一成员构造器。
 
 
 
 值类型的构造器代理:
 1、构造器可以通过调用其它构造器来完成实例的部分构造过程,这一过程称为构造器代理,它能避免多个构造器间的代码重复。
 2、如果你为某个值类型定义了一个自定义的构造器,你将无法访问到默认构造器(如果是结构体,还将无法访问逐一成员构造器)
 3、把自定义的构造器写到扩展(extension)中,而不是写在值类型的原始定义中。就能同时使用默认构造器、逐一成员构造器以及你自己的自定义构造器来创建实例了
 
 
 
 
 类的继承和构造过程:
 类类型的两种构造器:指定构造器 和 便利构造器。
 1、指定构造器:
 init(parameters) {
     statements
 }
 特点:
 a、指定构造器必须调用其直接父类的的指定构造器。
 指定构造器必须总是向上代理
 
 
 2、便利构造器:使用 convenience 关键字
 convenience init(parameters) {
     statements
 }
 特点:
 a、便利构造器必须调用同类中定义的其它构造器。
 b、便利构造器最后必须调用指定构造器。
 便利构造器必须总是横向代理

两段式构造过程:
第一个阶段:类中的每个存储型属性赋一个初始值。
第二阶段:当每个存储型属性的初始值被赋值后,第二阶段开始,它给每个类一次机会,在新实例准备使用之前进一步自定义它们的存储型属性。

Swift 编译器执行 4 种有效的安全检查,以确保两段式构造过程不出错:

1、指定构造器中必须将自己类的所有属性初始化完成,才能调用父类的构造器。
2、如果要为继承的属性设置值必须先调用父类的构造器。
3、便利构造器为任意属性(包括所有同类中定义的)赋新值之前,必须先调用其他构造器。
4、构造器在第一阶段构造完成之前,不能调用任何实例方法,不能读取任何实例属性的值,不能引用 self 作为一个值。

构造器的继承和重写:
 1、跟 Objective-C 中的子类不同,Swift 中的子类默认情况下不会继承父类的构造器。父类的构造器仅会在安全和适当的某些情况下被继承
 2、重写父类的指定构造器时要带上 override 修饰符。
 3、在子类中“重写” 父类的便利构造器时,不需要加 override 修饰符。
 4、子类中的便利构造器和父类的指定构造器匹配时,也要加上override 修饰符。
 如:init(name: String){} 是父类中的指定构造器。convenience init(name: String){} 是子类的便利构造器,要加上override 修饰符。
     override convenience init(name: String) {
         self.init(name: name, quantity: 1)
     }
 5、子类可以在构造过程修改继承来的变量属性,但是不能修改继承来的常量属性。
 
 
 
 构造器的自动继承:
 1、如果子类没有定义任何 指定构造器,它将自动继承父类所有的 指定构造器和便利构造器。
 2、如果子类提供了所有父类指定构造器的实现——无论是通过规则 1 继承过来的,还是提供了自定义实现——它将自动继承父类所有的便利构造器。
 
 
 
 可失败构造器:
 1、语法是在 init 关键字后面添加问号(init?)。
 2、可失败构造器的参数名和参数类型,不能与其它非可失败构造器的参数名,及其参数类型相同。
 3、可失败构造器会创建一个类型为自身类型的可选类型的对象。你通过 return nil 来表明可失败构造器的“失败”。
 
 
 
 枚举类型的可失败构造器:
 1、当形参不能和任何枚举成员相匹配时,则构造失败:
 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
         }
     }
 }
 
 let fahrenheitUnit = TemperatureUnit(symbol: "F") 会构造成功,fahrenheitUnit 不为 nil
 let unknownUnit = TemperatureUnit(symbol: "X") 会构造失败,unknownUnit 为 nil

 
 
 
 带原始值的枚举类型的可失败构造器:
 1、带原始值的枚举类型会自带一个可失败构造器 init?(rawValue:),有一个原始值类型 rawValue 的形参,如果能找到的相匹配的枚举成员则构造成功,找不到则构造失败。
 
 
 
 
 构造失败的传递:
 1、可失败构造器 可以调用本身或父类的其他可失败构造器或者非可失败构造器
 
 
 
 
 重写一个可失败构造器:
 1、可以用 非可失败构造器 重写 可失败构造器,但反过来却不行。
 即:子类中重写父类的可失败构造器,可以把这个构造器变为 非可失败构造器。但是不能把一个 非可失败构造器 变为 可失败构造器
 
 
 
 必要构造器:
 1、在类的 构造器前添加 required 修饰符表明所有该 类的子类 都 必须 实现该构造器
 2、重写父类的必要构造器时,不需要添加 override 修饰符,但是要添加 required 修饰符。
 3、如果子类继承的构造器能满足必要构造器的要求,则无须在子类中显式提供必要构造器的实现。
 
 
 
 
 通过闭包或函数设置属性的默认值:

 1、如果某个存储型属性的默认值需要一些自定义或设置,可以使用闭包或全局函数为其提供定制的默认值。
 2、每当创建新的实例时,对应的闭包或函数会被调用,而它们的返回值会当做默认值赋值给这个属性。
 3、在同一个实例中,即使不使用懒加载,就算多次获取这个属性的值,也只会执行一次对应的闭包或函数。
 class SomeClass {
     let someProperty: SomeType = {
        // 在闭包执行时,实例的其它部分都还没有初始化,因此不能在闭包里访问其它属性,即使这些属性有默认值。也不能使用self,或者调用任何实例方法。
        // 在这个闭包中给 someProperty 创建一个默认值
        // someValue 必须和 SomeType 类型相同
         return someValue
     }()    // 结尾加了(),表明立即执行此闭包。如果不加,则相当于将闭包本身作为值赋值给了属性,而不是将闭包的返回值赋值给属性。
 }

你可能感兴趣的:(iOS,swift,开发语言,ios)