子類(lèi)的構(gòu)造器
在闡明和辨別清楚指定構(gòu)造器和便利構(gòu)造器之后,我們就可以開(kāi)始了解子類(lèi)的構(gòu)造器了。
未聲明構(gòu)造器:
如果子類(lèi)不是必須有它自身的構(gòu)造器,并且如果它沒(méi)有聲明自身的構(gòu)造器,那么它繼承父類(lèi)的構(gòu)造器。
只有便利構(gòu)造器:
如果子類(lèi)不是必須有它自身的構(gòu)造器,它是有資格聲明便利構(gòu)造器的,因?yàn)槔^承提供了便利構(gòu)造器所需要的指定構(gòu)造器。
指定構(gòu)造器:
如果子類(lèi)定義了自身的指定構(gòu)造器,整件事情就不一樣了。
這種情況下,構(gòu)造器就不被繼承了。顯式指定構(gòu)造器的存在阻礙了構(gòu)造器的繼承?,F(xiàn)在子類(lèi)的構(gòu)造器就只有顯式指定的構(gòu)造器了。(還有一個(gè)例外將在一會(huì)兒講解)
每一個(gè)子類(lèi)的指定構(gòu)造器現(xiàn)在有一個(gè)額外的要求:它必須通過(guò)super.init( )調(diào)用一個(gè)父類(lèi)的指定構(gòu)造器。此外,調(diào)用self 的規(guī)則依然適用。一個(gè)子類(lèi)的指定構(gòu)造器必須按照如下的順序和要求:
1、它必須保證這個(gè)子類(lèi)的所有屬性均被初始化。
2、它必須調(diào)用super.init( )并且這個(gè)被調(diào)用的構(gòu)造器必須是指定構(gòu)造器
3、現(xiàn)在,它才可以使用self去干別的事情:調(diào)用實(shí)例方法或者獲取繼承的屬性。
子類(lèi)中的便利構(gòu)造器還是應(yīng)該遵守先前提到的規(guī)則。他們必須調(diào)用self.init( )來(lái)直接或者間接地調(diào)用一個(gè)指定構(gòu)造器。在沒(méi)有繼承構(gòu)造器的情況下,便利構(gòu)造器調(diào)用的構(gòu)造器必須是在子類(lèi)中出現(xiàn)的。
WARNING:
如果一個(gè)指定構(gòu)造器不調(diào)用super.init(...),那么如果可能,super.init(...)將被隱式調(diào)用。下面的代碼是合法的:
class Cat ?{
? ? ?}
class NamedCat : Cat ?{
? ? ? ? ?let name : String
? ? ? ? ?init(name:String) {
? ? ? ? ? ? ? ? ?self.name = name
? ? ? ? ? ? ?}
? ? ?}
在我看來(lái),這個(gè)swift特性是一個(gè)錯(cuò)漏。swift不應(yīng)該縱容這種隱蔽的方法,即使它可能是“有幫助的”。我覺(jué)得這段代碼不應(yīng)該可以編譯。一個(gè)指定構(gòu)造器始終必須顯式調(diào)用super.init(...)