swift初始化

默認(rèn)構(gòu)造器 和 結(jié)構(gòu)體的逐一成員構(gòu)造器

如果一個class或struct提供了默認(rèn)值,同時沒有定義任何構(gòu)造器那么會自動提供一個默認(rèn)構(gòu)造器(default initializers)。如:

class Person {
    var firstName = "Nero"
    var lastName = "Zuo"
}
let person = Person()

結(jié)構(gòu)體的逐一成員構(gòu)造器,

struct Circle {
    var center: CGPoint = CGPoint(x: 0, y: 2)
    var radius: CGFloat = 2
}
let circle0 = Circle(center: CGPoint(x: 0, y: 0), radius: 1) //逐一成員構(gòu)造器
let circle1 = Circle() //默認(rèn)構(gòu)造器

指定構(gòu)造器(Designated)和便利構(gòu)造器(Convenience)

class Shape {
    var lineWidth: CGFloat
    init(lineWidth: CGFloat) {
        self.lineWidth = lineWidth
    }

    convenience init() {
        self.init(lineWidth: 1)
    }   
}

這里init(lineWidth: CGFloat)是指定構(gòu)造器,convenience init()是便利構(gòu)造器,使用convenience關(guān)鍵字

繼承中的構(gòu)造器

自動繼承構(gòu)造器

如果子類沒有寫任何指定構(gòu)造器,那么子類就繼承繼承父類的所有構(gòu)造器,包括便利構(gòu)造器,同時你可以增加遍歷構(gòu)造器但不用重寫指定構(gòu)造器

class Shape {
    var lineWidth: CGFloat
    init(lineWidth: CGFloat) {
        self.lineWidth = lineWidth
    }

    convenience init() {
        self.init(lineWidth: 1)
    }
}

class Circle: Shape {
    convenience init(value: Int) {
        self.init()
        //self.init(lineWidth: 1) //這同樣可以
    }
}

let circle0 = Circle()
let circle1 = Circle(lineWidth: 2)
let circle2 = circle(value: 1)

注意:便利構(gòu)造器一定要調(diào)用self的構(gòu)造的,而不是super。這里看真好像調(diào)用了super的,但是這里Circle類自動繼承了父類的所有構(gòu)造器。


如果子類把所有的指定構(gòu)造器重寫了,那么父類的便利構(gòu)造器也會自動繼承

class Shape {
    var lineWidth: CGFloat
    init(lineWidth: CGFloat) {
        self.lineWidth = lineWidth
    }

    convenience init() {
        self.init(lineWidth: 1)
    }
}

class Circle: Shape {

    var radius: CGFloat

    init(radius: CGFloat) {
        self.radius = radius
        super.init(lineWidth: 2)
    }

    override init(lineWidth: CGFloat) {
        self.radius = 2
        super.init(lineWidth: lineWidth)
    }

}

let circle0 = Circle(lineWidth: 1) //成功
let circle1 = Circle() //成功,父類的便利構(gòu)造器繼承下來了
let circle2 = Circle(radius: 1) //成功

這里舉得例子不是很好,但能說明自動繼承,和下面的那段類似代碼對比看更好。

構(gòu)造器的繼承和重寫

當(dāng)你定義了一個的新的構(gòu)造器時,那么在此構(gòu)造器你必須新調(diào)用父類的指定構(gòu)造器(待會兒說道構(gòu)造過程時會具體講到)。

class Shape {
    var lineWidth: CGFloat
    init(lineWidth: CGFloat) {
        self.lineWidth = lineWidth
    }

    convenience init() {
        self.init(lineWidth: 1)
    }
}


class Circle: Shape {
    var radius: CGFloat

    init(radius: CGFloat) {
        self.radius = radius
        super.init(lineWidth: 2)
    }
}

let circle0 = Circle(lineWidth: 1) //錯誤,不能初始化,因為沒有重寫
let circle1 = Circle() //錯誤,不能初始化
let circle2 = Circle(radius: CGFloat) //成功

這里的父類的init(lineWidth: CGFloat)convenience init()都不能在子類里用了,因為沒有重寫。
重寫構(gòu)造器只能重寫父類的指定的構(gòu)造器,加上關(guān)鍵字override。

兩段式構(gòu)造過程

第一階段:

我的理解是類似不斷遞歸的過程,最下面的子類給自己新的存儲屬性賦值,然后調(diào)用父類的指定構(gòu)造器(不能調(diào)用父類的便利構(gòu)造器),父類的構(gòu)造器也是這個過程,不斷往上,打到最上面時結(jié)束

第二階段:

此時可以使用self,從上到下對對屬性進(jìn)一步定制化。

一句話總結(jié)指定構(gòu)造器和便利構(gòu)造器是指定構(gòu)造器縱向代理,遍歷構(gòu)造器橫向代理

必要構(gòu)造器(Required)

如果子類中重寫或定義了指定構(gòu)造器,就必須在子類中實現(xiàn)這個必要構(gòu)造器,且不需要加上override關(guān)鍵字,只需要加上required。

遇到最多的就是必要構(gòu)造器就是required init?(coder aDecoder: NSCoder)
這個在iOS中,如UIView, UIViewController等中經(jīng)常出現(xiàn),遵循了NSCoding協(xié)議,用于歸檔轉(zhuǎn)碼等。

可失敗構(gòu)造器

類似這樣的是可失敗構(gòu)造器,這個返回的是這個類的optional。

init?(){ }

淺見覺得調(diào)用這個(便利或指定)的構(gòu)造器都需要是可失敗構(gòu)造器

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容