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