兩種構(gòu)造器
Swift中為確保類在創(chuàng)建時(shí)每個(gè)屬性都會(huì)被初始化,定義了兩種構(gòu)造器,分別為指定構(gòu)造器(designated initializer)和便利構(gòu)造器(convenience initializer)郊供,每一個(gè)類都要至少包含一個(gè)指定構(gòu)造器玫锋,而兩種構(gòu)造器之間的調(diào)用要符合以下三條規(guī)則:
規(guī)則1
指定構(gòu)造器必須調(diào)用其直接父類的指定構(gòu)造器
規(guī)則2
便利構(gòu)造器必須調(diào)用同一類中定義的其它構(gòu)造器
規(guī)則3
便利構(gòu)造器必須最終以調(diào)用一個(gè)指定構(gòu)造器結(jié)束
即:指定構(gòu)造器必須向上代理
便利構(gòu)造器必須橫向代理
關(guān)系如下圖所示:
初始化的兩個(gè)階段(兩段式構(gòu)造過程)
Swift中類的構(gòu)造包含兩個(gè)階段。簡(jiǎn)單來說慧域,就是要保證屬性先初始化榆骚,然后才能對(duì)屬性進(jìn)行操作片拍。具體來講就是:
階段一
- 一個(gè)類的指定或便利初始化器需被調(diào)用
- 類的實(shí)例的內(nèi)存被申請(qǐng),但還沒有初始化
- 指定初始化器確保當(dāng)前類引入的所有儲(chǔ)存屬性都初始化
- 指定初始化器調(diào)用其父類的指定初始化器妓肢,繼續(xù)讓父類去初始化它所引入的儲(chǔ)存屬性
- 上面這個(gè)過程一直進(jìn)行直到最終的根類的指定初始化器被調(diào)用
- 當(dāng)根類的指定初始化器調(diào)用后捌省,該類的實(shí)例就已經(jīng)確保了所有儲(chǔ)存屬性都已經(jīng)初始化完成,階段一完成碉钠。
階段二
- 步驟二是從根類的指定初始化器開始的纲缓,一層層到最終的子類的指定初始化器
- 在這個(gè)步驟中,每個(gè)類都有機(jī)會(huì)對(duì)已經(jīng)步驟一中初始化完成的實(shí)例再次進(jìn)行自定義修改放钦。此時(shí)初始化器已經(jīng)可以訪問 self色徘,修改屬性或者調(diào)用實(shí)例方法了恭金。
構(gòu)造器的繼承和重載
Swift中子類默認(rèn)并不會(huì)自動(dòng)繼承父類的init方法操禀,除非是給新加屬性一個(gè)默認(rèn)值,這種情況下才會(huì)自動(dòng)繼承父類init方法横腿。有以下規(guī)則:
規(guī)則一:
如果你的子類沒有定義任何指定初始化器颓屑,則其會(huì)自動(dòng)繼承其父類的所有指定初始化器
規(guī)則二:
如果你的子類實(shí)現(xiàn)了其父類的所有指定初始化器斤寂,不管是自定義的實(shí)現(xiàn)還是因?yàn)橐?guī)則一造成的實(shí)現(xiàn),該子類自動(dòng)繼承其父類所有的便利初始化器揪惦。
需要注意的是遍搞,如果在子類定義了自己的指定構(gòu)造器,那么將不會(huì)繼承任何父類的構(gòu)造方法了器腋,如果想繼承溪猿,需要用override修飾