100 Days of SwiftUI - Day 10 Class 類

Class 類

類與結構體非常相似洒嗤,我們都用它創(chuàng)建具有屬性和方法的新數據類型粗俱。但是類引入了一個新的,重要而且復雜的功能-繼承澳化,使一個類建立在另一個類的基礎上的能力崔步。
繼承是一個強大的功能稳吮,但是請記住要使代碼保持簡單:功能存在缎谷,但不意味著你需要使用它。
“任何傻瓜都可以編寫計算機可以理解的代碼灶似,但是優(yōu)秀的程序員可以編寫人類可以理解的代碼列林。”——Martin Fowler酪惭。
SwiftUI中廣泛使用結構體希痴,而數據中廣泛使用了類。
與以前使用UIKit時春感,是非常不同的砌创,UIKit中我們使用類進行UI設計,而使用結構體進行數據處理鲫懒。

1.創(chuàng)建類

類與結構體的第一個區(qū)別就是嫩实,類中不會帶有默認的成員初始化器。如果類中有屬性窥岩,則必須創(chuàng)建自己的初始化方法甲献。

class Dog {
    var name: String
    var breed: String

    init(name: String, breed: String) {
        self.name = name
        self.breed = breed
    }
}
let poppy = Dog(name: "Poppy", breed: "Poodle")

創(chuàng)建類的實例看起來和結構體一樣。

為什么Swift要有類和結構體?

它們之間有五個重要的區(qū)別颂翼,后面我們詳細解釋這些差異晃洒。
1.類不帶有合成的成員初始化器。
2.類可以通過繼承朦乏,從而獲得另一個類的屬性和方法球及。
3.結構體的副本始終是唯一的,而類的副本實際上指向相同的共享數據呻疹。
4.類具有反初始化器吃引,當類的實例被銷毀時,會調用這些方法诲宇,而結構體不會际歼。
5.常量類中的變量屬性可以自由修改,而常量結構體中的變量不能隨意修改姑蓝。

2.類的繼承

類與結構體的第二個區(qū)別鹅心,就是你可以基于現有類創(chuàng)建另一個類,它繼承了原始類的所有屬性和方法纺荧,并且可以添加自己的屬性和方法旭愧。
這稱為類的繼承或者子類化颅筋,被繼承的類稱為"父類"或“超類”,新的類稱為“子類”输枯。

基于剛才我們創(chuàng)建的類议泵,我們創(chuàng)建一個Poodle

class Poodle: Dog {
  init(name: String) {
        super.init(name: name, breed: "Poodle")
    }
}

因為Poodle具有自己固定的品種,所有我們提供了一個僅需要name的初始化方法桃熄。
Swift總是要求在子類調用 super.init方法先口,防止父類在創(chuàng)建時做一些重要工作。

為什么類不具有成員初始化器瞳收?
因為類有繼承碉京,使得成員初始化方法很難使用,當繼承一個類后螟深,然后在子類中添加了一些屬性谐宙,此時父類的成員初始化方法在子類中將不再有用,所以界弧,Swift讓我自己提供成員初始化方法凡蜻。不管添加任意數量的屬性,都不影響類的繼承垢箕。

3.重載 override

子類可以用自己的實現替換父類方法划栓。
比如下面這個帶有makeNoise()方法的普通類。

class Dog {
    func makeNoise() {
        print("Woof!")
    }
}

我們創(chuàng)建一個繼承的新類舰讹。通過重載override func父類方法茅姜。

class Poodle: Dog {
    override func makeNoise() {
        print("Yip!")
    }
}
let poppy = Poodle()
poppy.makeNoise()

更改后,poppy.makeNoise()將打印“Yip!”月匣。

4.final class

如果你不想讓其他類繼承你的類钻洒,你可以將類聲明為final,其它類將不能繼承锄开。
在類前添加final:

final class Dog {
    var name: String
    var breed: String

    init(name: String, breed: String) {
        self.name = name
        self.breed = breed
    }
}

final以前可以帶來一點點的性能提升素标,更重要的是final讓人更容易理解你的代碼。

5. Copy

類與結構體的第三個區(qū)別是Copy萍悴。結構體拷貝后头遭,原始和復制的結構體是不同的,改變一個不會更改其它的結構體癣诱,而類原始副本和復制副本指向了同一個事物计维,因此更改一個會更改另一個。

class Singer {
    var name = "Taylor Swift"
}
var singer = Singer()
print(singer.name)
var singerCopy = singer
singerCopy.name = "Justin Bieber"
print(singer.name)

我們看到singer的名字已經變化撕予。
如果改為結構體鲫惶,兩次將打印相同的結果。

為什么類要共享數據实抡?

類的副本共享基礎數據欠母,結構體始終具有自身的唯一數據欢策。
這種區(qū)別叫做“值類型與引用類型”。結構體是值類型赏淌,類時引用類型踩寇。
結構體的值萬千包含在變量內,而引用類型復制時六水,會獲得一個新的指針俺孙,指向原始對象所在的內存。
Swift人員更喜歡將結構體用于自定義類型缩擂,比如在一個大型程序中共享一個user對象時鼠冕,如果使用的是類,有人把user數據改掉卻不知道時胯盯,很可能會遇到問題。
有時候將要共享的東西计露,使用類改變時并通過一些方式發(fā)送消息給其他人博脑,可能比拷貝一些對象更好一些。

6.Deinit

類和結構體之間的第四個區(qū)別是票罐,類具有反初始化叉趣,在類被銷毀時運行。

class Person {
    var name = "John Doe"

    init() {
        print("\(name) is alive!")
    }

    func printGreeting() {
        print("Hello, I'm \(name)")
    }
    deinit {
        print("\(name) is no more!")
    }
}

類為什么有deinit?

因為類的復制行為该押,很難判斷類何時被銷毀,Swift有”自動引用計數“的操作疗杉,ARC自動跟蹤類的副本,當每次獲得一個副本蚕礼,Swift對其引用計數+1,每次被銷毀時烟具,Swift對其引用計數中-1,計數為0時,Swift調用反初始化程序并銷毀該對象奠蹬。
結構體有其自己的副本朝聋,不需要反初始化。

7.類的Mutability

類與結構體最終區(qū)別是囤躁,處理常量的方式冀痕。常量的結構體,屬性不能更改狸演,而類可以言蛇。
類不需要mutating關鍵字。
為什么可以更改常量類中的變量屬性?

原因在于宵距,一個指向的是內存中的某些數據腊尚,而另一個指向值。
結構體更改屬性時消玄,實際上是在更改整個結構跟伏。而類不會破壞并重新創(chuàng)建值丢胚。所以常量類可以自由更改變量屬性。

8.總結

1.類和結構體類似受扳,都可以使用屬性和方法創(chuàng)建自己的類型携龟。
2.一個類可以從另一類繼承,并獲得父類所有屬性和方法勘高。
3.final關鍵字標記一個類峡蟋,阻止其它類繼承。
4.通過重寫华望,子類可以使用新的實現替換父類方法蕊蝗。
5.當兩個變量指向同一個實例時,他們指向同一塊內存赖舟。
6.類有deinit,銷毀時運行蓬戚。
7.將屬性聲明為變量時,無論類實例為常量或變量宾抓,都可以更改屬性子漩。

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市石洗,隨后出現的幾起案子幢泼,更是在濱河造成了極大的恐慌,老刑警劉巖讲衫,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缕棵,死亡現場離奇詭異,居然都是意外死亡涉兽,警方通過查閱死者的電腦和手機招驴,發(fā)現死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來花椭,“玉大人忽匈,你說我怎么就攤上這事】罅桑” “怎么了丹允?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長袋倔。 經常有香客問我雕蔽,道長,這世上最難降的妖魔是什么宾娜? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任批狐,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘嚣艇。我一直安慰自己承冰,他們只是感情好,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布食零。 她就那樣靜靜地躺著困乒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪贰谣。 梳的紋絲不亂的頭發(fā)上娜搂,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機與錄音吱抚,去河邊找鬼百宇。 笑死,一個胖子當著我的面吹牛秘豹,可吹牛的內容都是我干的携御。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼憋肖,長吁一口氣:“原來是場噩夢啊……” “哼因痛!你這毒婦竟也來了?” 一聲冷哼從身側響起岸更,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎膊升,沒想到半個月后怎炊,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡廓译,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年评肆,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片非区。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡瓜挽,死狀恐怖,靈堂內的尸體忽然破棺而出征绸,到底是詐尸還是另有隱情久橙,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布管怠,位于F島的核電站淆衷,受9級特大地震影響,放射性物質發(fā)生泄漏渤弛。R本人自食惡果不足惜祝拯,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望她肯。 院中可真熱鬧佳头,春花似錦鹰贵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至凄鼻,卻和暖如春腊瑟,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背块蚌。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工闰非, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人峭范。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓财松,卻偏偏與公主長得像,于是被迫代替她去往敵國和親纱控。 傳聞我的和親對象是個殘疾皇子辆毡,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345