構(gòu)造器可以通過調(diào)用其它構(gòu)造器來完成實(shí)例的部分構(gòu)造過程。這一過程稱為構(gòu)造器代理,它能減少多個構(gòu)造器間的代碼重復(fù)。
構(gòu)造器代理的實(shí)現(xiàn)規(guī)則和形式在值類型和類類型中有所不同。值類型(結(jié)構(gòu)體和枚舉類型)不支持繼承,所以構(gòu)造器代理的過程相對簡單,因?yàn)樗鼈冎荒艽砣蝿?wù)給本身提供的其它構(gòu)造器。類則不同,它可以繼承自其它類(請參考繼承),這意味著類有責(zé)任保證其所有繼承的存儲型屬性在構(gòu)造時(shí)也能正確的初始化。這些責(zé)任將在后續(xù)章節(jié)類的繼承和構(gòu)造過程中介紹。
對于值類型,你可以使用self.init在自定義的構(gòu)造器中引用其它的屬于相同值類型的構(gòu)造器。并且你只能在構(gòu)造器內(nèi)部調(diào)用self.init。
注意,如果你為某個值類型定義了一個定制的構(gòu)造器,你將無法訪問到默認(rèn)構(gòu)造器(如果是結(jié)構(gòu)體,則無法訪問逐一對象構(gòu)造器)。這個限制可以防止你在為值類型定義了一個更復(fù)雜的,完成了重要準(zhǔn)備構(gòu)造器之后,別人還是錯誤的使用了那個自動生成的構(gòu)造器。
注意:
假如你想通過默認(rèn)構(gòu)造器、逐一對象構(gòu)造器以及你自己定制的構(gòu)造器為值類型創(chuàng)建實(shí)例,我們建議你將自己定制的構(gòu)造器寫到擴(kuò)展(extension)中,而不是跟值類型定義混在一起。想查看更多內(nèi)容,請查看擴(kuò)展章節(jié)。
下面例子將定義一個結(jié)構(gòu)體Rect,用來展現(xiàn)幾何矩形。這個例子需要兩個輔助的結(jié)構(gòu)體Size和Point,它們各自為其所有的屬性提供了初始值0.0。
struct Size {
var width = 0.0, height = 0.0
}
struct Point {
var x = 0.0, y = 0.0
}
你可以通過以下三種方式為Rect創(chuàng)建實(shí)例--使用默認(rèn)的0值來初始化origin和size屬性;使用特定的origin和size實(shí)例來初始化;使用特定的center和size來初始化。在下面Rect結(jié)構(gòu)體定義中,我們?yōu)橹N方式提供了三個自定義的構(gòu)造器:
struct Rect {
var origin = Point()
var size = Size()
init() {}
init(origin: Point, size: Size) {
self.origin = origin
self.size = size
}
init(center: Point, size: Size) {
let originX = center.x - (size.width / 2)
let originY = center.y - (size.height / 2)
self.init(origin: Point(x: originX, y: originY), size: size)
}
}
第一個Rect構(gòu)造器init(),在功能上跟沒有自定義構(gòu)造器時(shí)自動獲得的默認(rèn)構(gòu)造器是一樣的。這個構(gòu)造器是一個空函數(shù),使用一對大括號{}來描述,它沒有執(zhí)行任何定制的構(gòu)造過程。調(diào)用這個構(gòu)造器將返回一個Rect實(shí)例,它的origin和size屬性都使用定義時(shí)的默認(rèn)值Point(x: 0.0, y: 0.0)和Size(width: 0.0, height: 0.0):
let basicRect = Rect()
// basicRect 的原點(diǎn)是 (0.0, 0.0),尺寸是 (0.0, 0.0)
第二個Rect構(gòu)造器init(origin:size:),在功能上跟結(jié)構(gòu)體在沒有自定義構(gòu)造器時(shí)獲得的逐一成員構(gòu)造器是一樣的。這個構(gòu)造器只是簡單的將origin和size的參數(shù)值賦給對應(yīng)的存儲型屬性:
let originRect = Rect(origin: Point(x: 2.0, y: 2.0),
size: Size(width: 5.0, height: 5.0))
// originRect 的原點(diǎn)是 (2.0, 2.0),尺寸是 (5.0, 5.0)
第三個Rect構(gòu)造器init(center:size:)稍微復(fù)雜一點(diǎn)。它先通過center和size的值計(jì)算出origin的坐標(biāo)。然后再調(diào)用(或代理給)init(origin:size:)構(gòu)造器來將新的origin和上一篇:Swift自動引用計(jì)數(shù)實(shí)踐下一篇:Swift break語句