Swift 六

繼承

定義一個基類 :不繼承于其它類的類,稱之為基類

重寫:如果要重寫某個特性当船,你需要在重寫定義的前面加上?override?關(guān)鍵字

override?關(guān)鍵字會提醒 Swift 編譯器去檢查該類的超類(或其中一個父類)是否有匹配重寫版本的聲明沦零。這個檢查可以確保你的重寫定義是正確的。

你不可以為繼承來的常量存儲型屬性或繼承來的只讀計(jì)算型屬性添加屬性觀察器篮灼。這些屬性的值是不可以被設(shè)置的忘古,所以,為它們提供?willSet?或?didSet?實(shí)現(xiàn)也是不恰當(dāng)诅诱。 此外還要注意髓堪,你不可以同時提供重寫的 setter 和重寫的屬性觀察器。如果你想觀察屬性值的變化逢艘,并且你已經(jīng)為那個屬性提供了定制的 setter旦袋,那么你在 setter 中就可以觀察到任何值變化了。

防止重寫?

你可以通過把方法它改,屬性或下標(biāo)標(biāo)記為?final?來防止它們被重寫疤孕,只需要在聲明關(guān)鍵字前加上?final修飾符即可(例如:final var、final func央拖、final class func?以及?final subscript)祭阀。

任何試圖對帶有?final?標(biāo)記的方法鹉戚、屬性或下標(biāo)進(jìn)行重寫的代碼,都會在編譯時會報錯专控。在類擴(kuò)展中的方法抹凳,屬性或下標(biāo)也可以在擴(kuò)展的定義里標(biāo)記為?final。

可以通過在關(guān)鍵字?class?前添加?final?修飾符(final class)來將整個類標(biāo)記為 final 伦腐。這樣的類是不可被繼承的赢底,試圖繼承這樣的類會導(dǎo)致編譯報錯。

構(gòu)造過程:

構(gòu)造過程是使用類柏蘑、結(jié)構(gòu)體或枚舉類型的實(shí)例之前的準(zhǔn)備過程幸冻。在新實(shí)例使用前有個過程是必須的,它包括設(shè)置實(shí)例中每個存儲屬性的初始值和執(zhí)行其他必須的設(shè)置或構(gòu)造過程咳焚。

通過定義構(gòu)造器來實(shí)現(xiàn)構(gòu)造過程洽损。

與 Objective-C 中的構(gòu)造器不同,Swift 的構(gòu)造器沒有返回值革半。它們的主要任務(wù)是保證某種類型的新實(shí)例在第一次使用前完成正確的初始化碑定。

類和結(jié)構(gòu)體在創(chuàng)建實(shí)例時,必須為所有存儲型屬性設(shè)置合適的初始值又官。存儲型屬性的值不能處于一個未知的狀態(tài)延刘。你可以在構(gòu)造器中為存儲型屬性設(shè)置初始值,也可以在定義屬性時分配默認(rèn)值赏胚。以下小節(jié)將詳細(xì)介紹這兩種方法访娶。

構(gòu)造器 :構(gòu)造器在創(chuàng)建某個特定類型的新實(shí)例時被調(diào)用。它的最簡形式類似于一個不帶任何形參的實(shí)例方法觉阅,以關(guān)鍵字?init?命名:

init () {

? ? ? ? //在此執(zhí)行構(gòu)造過程

}

如果一個屬性總是使用相同的初始值崖疤,那么為其設(shè)置一個默認(rèn)值比每次都在構(gòu)造器中賦值要好。兩種方法的最終結(jié)果是一樣的典勇,只不過使用默認(rèn)值讓屬性的初始化和聲明結(jié)合得更緊密劫哼。

注意,如果不通過實(shí)參標(biāo)簽傳值割笙,這個構(gòu)造器是沒法調(diào)用的权烧。如果構(gòu)造器定義了某個實(shí)參標(biāo)簽,就必須使用它伤溉,忽略它將導(dǎo)致編譯期錯誤:

如果你不希望構(gòu)造器的某個形參使用實(shí)參標(biāo)簽般码,可以使用下劃線(_)來代替顯式的實(shí)參標(biāo)簽來重寫默認(rèn)行為。

可選屬性類型 :如果你自定義的類型有一個邏輯上允許值為空的存儲型屬性——無論是因?yàn)樗鼰o法在初始化時賦值乱顾,還是因?yàn)樗谥竽硞€時機(jī)可以賦值為空——都需要將它聲明為?可選類型板祝。可選類型的屬性將自動初始化為?nil走净,表示這個屬性是特意在構(gòu)造過程設(shè)置為空券时。

構(gòu)造過程中常量屬性的賦值 :你可以在構(gòu)造過程中的任意時間點(diǎn)給常量屬性賦值孤里,只要在構(gòu)造過程結(jié)束時它設(shè)置成確定的值。一旦常量屬性被賦值橘洞,它將永遠(yuǎn)不可更改捌袜。

注意:對于類的實(shí)例來說,它的常量屬性只能在定義它的類的構(gòu)造過程中修改炸枣;不能在子類中修改虏等。

結(jié)構(gòu)體的逐一成員構(gòu)造器 :結(jié)構(gòu)體如果沒有定義任何自定義構(gòu)造器,它們將自動獲得一個逐一成員構(gòu)造器(memberwise initializer)适肠。不像默認(rèn)構(gòu)造器博其,即使存儲型屬性沒有默認(rèn)值,結(jié)構(gòu)體也能會獲得逐一成員構(gòu)造器迂猴。

如果你為某個值類型定義了一個自定義的構(gòu)造器,你將無法訪問到默認(rèn)構(gòu)造器(如果是結(jié)構(gòu)體背伴,還將無法訪問逐一成員構(gòu)造器)沸毁。這種限制避免了在一個更復(fù)雜的構(gòu)造器中做了額外的重要設(shè)置,但有人不小心使用自動生成的構(gòu)造器而導(dǎo)致錯誤的情況傻寂。

值類型的構(gòu)造器代理 :構(gòu)造器可以通過調(diào)用其它構(gòu)造器來完成實(shí)例的部分構(gòu)造過程息尺。這一過程稱為構(gòu)造器代理,它能避免多個構(gòu)造器間的代碼重復(fù)疾掰。

類的繼承和構(gòu)造過程 :類里面的所有存儲型屬性——包括所有繼承自父類的屬性——都必須在構(gòu)造過程中設(shè)置初始值搂誉。

Swift 為類類型提供了兩種構(gòu)造器來確保實(shí)例中所有存儲型屬性都能獲得初始值,它們被稱為指定構(gòu)造器便利構(gòu)造器静檬。

指定構(gòu)造器是類中最主要的構(gòu)造器炭懊。一個指定構(gòu)造器將初始化類中提供的所有屬性,并調(diào)用合適的父類構(gòu)造器讓構(gòu)造過程沿著父類鏈繼續(xù)往上進(jìn)行拂檩。

便利構(gòu)造器是類中比較次要的侮腹、輔助型的構(gòu)造器胚委。你可以定義便利構(gòu)造器來調(diào)用同一個類中的指定構(gòu)造器毫别,并為部分形參提供默認(rèn)值魄缚。你也可以定義便利構(gòu)造器來創(chuàng)建一個特殊用途或特定輸入值的實(shí)例霞扬。

指定構(gòu)造器和便利構(gòu)造器的語法?

類的指定構(gòu)造器的寫法跟值類型簡單構(gòu)造器一樣:

init (parameters){

? ? ? ?statements

}

便利構(gòu)造器也采用相同樣式的寫法撒顿,但需要在?init?關(guān)鍵字之前放置?convenience?關(guān)鍵字芥备,并使用空格將它們倆分開:

convenience init (parameters) {

? ? ? ? ?statements

}

類類型的構(gòu)造器代理?

為了簡化指定構(gòu)造器和便利構(gòu)造器之間的調(diào)用關(guān)系塞耕,Swift 構(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òu)造器斟览。

一個更方便記憶的方法是:

指定構(gòu)造器必須總是向上代理

便利構(gòu)造器必須總是橫向代理

構(gòu)造器的繼承和重寫 :跟 Objective-C 中的子類不同,Swift 中的子類默認(rèn)情況下不會繼承父類的構(gòu)造器舰蟆。Swift 的這種機(jī)制可以防止一個父類的簡單構(gòu)造器被一個更精細(xì)的子類繼承趣惠,而在用來創(chuàng)建子類時的新實(shí)例時沒有完全或錯誤被初始化狸棍。

可失敗構(gòu)造器:這里所指的“失敗” 指的是,如給構(gòu)造器傳入無效的形參味悄,或缺少某種所需的外部資源草戈,又或是不滿足某種必要的條件等。為了妥善處理這種構(gòu)造過程中可能會失敗的情況侍瑟。你可以在一個類唐片,結(jié)構(gòu)體或是枚舉類型的定義中,添加一個或多個可失敗構(gòu)造器涨颜。其語法為在?init?關(guān)鍵字后面添加問號(init?)费韭。可失敗構(gòu)造器會創(chuàng)建一個類型為自身類型的可選類型的對象庭瑰。你通過?return nil?語句來表明可失敗構(gòu)造器在何種情況下應(yīng)該 “失敗”星持。

注意

嚴(yán)格來說,構(gòu)造器都不支持返回值弹灭。因?yàn)闃?gòu)造器本身的作用督暂,只是為了確保對象能被正確構(gòu)造。因此你只是用?return nil?表明可失敗構(gòu)造器構(gòu)造失敗穷吮,而不要用關(guān)鍵字?return?來表明構(gòu)造成功逻翁。

枚舉類型的可失敗構(gòu)造器 :你可以通過一個帶一個或多個形參的可失敗構(gòu)造器來獲取枚舉類型中特定的枚舉成員。如果提供的形參無法匹配任何枚舉成員捡鱼,則構(gòu)造失敗八回。

帶原始值的枚舉類型的可失敗構(gòu)造器 :帶原始值的枚舉類型會自帶一個可失敗構(gòu)造器?init?(rawValue:),該可失敗構(gòu)造器有一個合適的原始值類型的?rawValue?形參驾诈,選擇找到的相匹配的枚舉成員缠诅,找不到則構(gòu)造失敗。

構(gòu)造失敗的傳遞 ::類翘鸭、結(jié)構(gòu)體滴铅、枚舉的可失敗構(gòu)造器可以橫向代理到它們自己其他的可失敗構(gòu)造器。類似的就乓,子類的可失敗構(gòu)造器也能向上代理到父類的可失敗構(gòu)造器汉匙。

無論是向上代理還是橫向代理,如果你代理到的其他可失敗構(gòu)造器觸發(fā)構(gòu)造失敗生蚁,整個構(gòu)造過程將立即終止噩翠,接下來的任何構(gòu)造代碼不會再被執(zhí)行。

必要構(gòu)造器 :在類的構(gòu)造器前添加?required?修飾符表明所有該類的子類都必須實(shí)現(xiàn)該構(gòu)造器:

class SomeClass {

? ? required init (){//構(gòu)造器的實(shí)現(xiàn)代碼}

}

在子類重寫父類的必要構(gòu)造器時邦投,必須在子類的構(gòu)造器前也添加?required?修飾符伤锚,表明該構(gòu)造器要求也應(yīng)用于繼承鏈后面的子類。在重寫父類中必要的指定構(gòu)造器時志衣,不需要添加?override?修飾符:

通過閉包或函數(shù)設(shè)置屬性的默認(rèn)值::如果某個存儲型屬性的默認(rèn)值需要一些自定義或設(shè)置屯援,你可以使用閉包或全局函數(shù)為其提供定制的默認(rèn)值猛们。每當(dāng)某個屬性所在類型的新實(shí)例被構(gòu)造時,對應(yīng)的閉包或函數(shù)會被調(diào)用狞洋,而它們的返回值會當(dāng)做默認(rèn)值賦值給這個屬性弯淘。

注意:閉包結(jié)尾的花括號后面接了一對空的小括號。這用來告訴 Swift 立即執(zhí)行此閉包吉懊。如果你忽略了這對括號庐橙,相當(dāng)于將閉包本身作為值賦值給了屬性,而不是將閉包的返回值賦值給屬性借嗽。

注意:如果你使用閉包來初始化屬性态鳖,請記住在閉包執(zhí)行時,實(shí)例的其它部分都還沒有初始化恶导。這意味著你不能在閉包里訪問其它屬性浆竭,即使這些屬性有默認(rèn)值。同樣惨寿,你也不能使用隱式的?self?屬性兆蕉,或者調(diào)用任何實(shí)例方法。

析構(gòu)過程

析構(gòu)器只適用于類類型缤沦,當(dāng)一個類的實(shí)例被釋放之前,析構(gòu)器會被立即調(diào)用易稠。析構(gòu)器用關(guān)鍵字?deinit來標(biāo)示缸废,類似于構(gòu)造器要用?init?來標(biāo)示。

析構(gòu)過程原理 :Swift 會自動釋放不再需要的實(shí)例以釋放資源驶社。如?自動引用計(jì)數(shù)?章節(jié)中所講述企量,Swift 通過自動引用計(jì)數(shù)(ARC)?處理實(shí)例的內(nèi)存管理。通常當(dāng)你的實(shí)例被釋放時不需要手動地去清理亡电。但是届巩,當(dāng)使用自己的資源時,你可能需要進(jìn)行一些額外的清理份乒。例如恕汇,如果創(chuàng)建了一個自定義的類來打開一個文件,并寫入一些數(shù)據(jù)或辖,你可能需要在類實(shí)例被釋放之前手動去關(guān)閉該文件瘾英。

在類的定義中,每個類最多只能有一個析構(gòu)器颂暇,而且析構(gòu)器不帶任何參數(shù)和圓括號缺谴,如下所示:

deinit { ?//執(zhí)行析構(gòu)過程

}

析構(gòu)器是在實(shí)例釋放發(fā)生前被自動調(diào)用的。你不能主動調(diào)用析構(gòu)器耳鸯。子類繼承了父類的析構(gòu)器湿蛔,并且在子類析構(gòu)器實(shí)現(xiàn)的最后膀曾,父類的析構(gòu)器會被自動調(diào)用。即使子類沒有提供自己的析構(gòu)器阳啥,父類的析構(gòu)器也同樣會被調(diào)用添谊。

因?yàn)橹钡綄?shí)例的析構(gòu)器被調(diào)用后,實(shí)例才會被釋放苫纤,所以析構(gòu)器可以訪問實(shí)例的所有屬性碉钠,并且可以根據(jù)那些屬性可以修改它的行為(比如查找一個需要被關(guān)閉的文件)。

可選鏈?zhǔn)秸{(diào)用

可選鏈?zhǔn)秸{(diào)用是一種可以在當(dāng)前值可能為?nil?的可選值上請求和調(diào)用屬性卷拘、方法及下標(biāo)的方法喊废。如果可選值有值,那么調(diào)用就會成功栗弟;如果可選值是?nil污筷,那么調(diào)用將返回?nil。多個調(diào)用可以連接在一起形成一個調(diào)用鏈乍赫,如果其中任何一個節(jié)點(diǎn)為?nil瓣蛀,整個調(diào)用鏈都會失敗,即返回?nil雷厂。

可選鏈?zhǔn)秸{(diào)用可以在空值(nil)上調(diào)用的事實(shí)惋增,不論這個調(diào)用的屬性、方法及下標(biāo)返回的值是不是可選值改鲫,它的返回結(jié)果都是一個可選值诈皿。你可以利用這個返回值來判斷你的可選鏈?zhǔn)秸{(diào)用是否調(diào)用成功,如果調(diào)用有返回值則說明調(diào)用成功像棘,返回?nil?則說明調(diào)用失敗稽亏。

這里需要特別指出,可選鏈?zhǔn)秸{(diào)用的返回結(jié)果與原本的返回結(jié)果具有相同的類型缕题,但是被包裝成了一個可選值

1.如果你訪問的值不是可選的截歉,可選鏈?zhǔn)秸{(diào)用將會返回可選值。

2.如果你訪問的值就是可選的烟零,可選鏈?zhǔn)秸{(diào)用不會讓可選返回值變得“更可選”瘪松。

因此:

3.通過可選鏈?zhǔn)秸{(diào)用訪問一個?Int?值,將會返回?Int?锨阿,無論使用了多少層可選鏈?zhǔn)秸{(diào)用凉逛。

4.類似的,通過可選鏈?zhǔn)秸{(diào)用訪問?Int??值群井,依舊會返回?Int??值状飞,并不會返回?Int??。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市诬辈,隨后出現(xiàn)的幾起案子酵使,更是在濱河造成了極大的恐慌,老刑警劉巖焙糟,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件口渔,死亡現(xiàn)場離奇詭異,居然都是意外死亡穿撮,警方通過查閱死者的電腦和手機(jī)缺脉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來悦穿,“玉大人攻礼,你說我怎么就攤上這事±跗猓” “怎么了礁扮?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長瞬沦。 經(jīng)常有香客問我太伊,道長,這世上最難降的妖魔是什么逛钻? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任僚焦,我火速辦了婚禮,結(jié)果婚禮上曙痘,老公的妹妹穿的比我還像新娘叠赐。我一直安慰自己,他們只是感情好屡江,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著赛不,像睡著了一般惩嘉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上踢故,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天文黎,我揣著相機(jī)與錄音,去河邊找鬼殿较。 笑死耸峭,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的淋纲。 我是一名探鬼主播劳闹,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了本涕?” 一聲冷哼從身側(cè)響起业汰,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎菩颖,沒想到半個月后样漆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡晦闰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年放祟,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片呻右。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡跪妥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出窿冯,到底是詐尸還是另有隱情骗奖,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布醒串,位于F島的核電站执桌,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏芜赌。R本人自食惡果不足惜仰挣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望缠沈。 院中可真熱鬧膘壶,春花似錦、人聲如沸洲愤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽柬赐。三九已至亡问,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間肛宋,已是汗流浹背州藕。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留酝陈,地道東北人床玻。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像沉帮,于是被迫代替她去往敵國和親锈死。 傳聞我的和親對象是個殘疾皇子贫堰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學(xué)習(xí)記錄文檔,今天18年5月份再次想寫文章馅精,發(fā)現(xiàn)簡書還為我保存起的...
    Jenaral閱讀 2,752評論 2 9
  • 本章將會介紹 存儲屬性的初始賦值自定義構(gòu)造過程默認(rèn)構(gòu)造器值類型的構(gòu)造器代理類的繼承和構(gòu)造過程可失敗構(gòu)造器必要構(gòu)造器...
    寒橋閱讀 769評論 0 0
  • 構(gòu)造過程是使用類洲敢、結(jié)構(gòu)體或枚舉類型的實(shí)例之前的準(zhǔn)備過程漫玄。在新實(shí)例可用前必須執(zhí)行這個過程,具體操作包括設(shè)置實(shí)例中每個...
    CDLOG閱讀 337評論 0 1
  • 下標(biāo)腳本 下標(biāo)腳本 可以定義在類压彭、結(jié)構(gòu)體和枚舉這些目標(biāo)中睦优,可以認(rèn)為是訪問集合(collection),列表(li...
    cht005288閱讀 448評論 0 0
  • 構(gòu)造過程是使用類壮不、結(jié)構(gòu)體或枚舉類型的實(shí)例之前的準(zhǔn)備過程汗盘。在新實(shí)例可用前必須執(zhí)行這個過程,具體操作包括設(shè)置實(shí)例中每個...
    莽原奔馬668閱讀 682評論 0 3