14 建構函式

2022-11-24 20:06:55 字數 3529 閱讀 8720

構造過程是使用類、結構體或列舉型別的例項之前的準備過程。在新例項可用前必須執行這個過程,具體操作包括設定例項中每個儲存型屬性的初始值和執行其他必須的設定或初始化工作。

與objective-c 中的構造器不同,swift 的構造器無需返回值,它們的主要任務是保證新例項在第一次使用前完成正確的初始化。

struct

inittest

}

struct

celsius

//帶外部名和內部名的構造器引數

init(fromkelvin kelvin: double)

//不帶外部名的構造器引數

init(_ celsius: double)

}//let bodytemperature = celsius(name: "hi", temperatureincelsius: 32, description: "hello world");

//錯誤:如果自定義了構造器, 那麼預設構造器會丟失;如果是結構體,還將丟失逐一成員構造器

let bodytemperature1 = celsius(fahrenheit: 100

);//

bodytemperature1.name = "hello";

//錯誤:常量屬性被賦值後將永遠不可更改。

let bodytemperature2 = celsius(fromkelvin: 300

);let bodytemperature3 = celsius(37.0);

struct

size

let zerobyzero = size(); //

預設構造器

let twobytwo = size(width: 2.0, height: 2.0); //

逐一成員構造器

struct

size

struct

point

struct

rect

init(origin: point, size: size)

init(center: point, size: size)

}let centerrect = rect(center: point(x: 4.0, y: 4.0

), size: size(width:

3.0, height: 3.0));

//

指定構造器

init(parameters)

//便利構造器

convenience init(parameters)

指定構造器必須呼叫其直接父類的的指定構造器。

便利構造器必須呼叫同一類中定義的其它構造器。

便利構造器必須最終導致一個指定構造器被呼叫。

如下圖所示:

跟objective-c 中的子類不同,swift 中的子類預設情況下不會繼承父類的構造器。swift 的這種機制可以防止一個父類的簡單構造器被一個更專業的子類繼承,並被錯誤地用來建立子類的例項。

子類在預設情況下不會繼承父類的構造器。但是如果滿足特定條件,父類構造器是可以被自動繼承的。

假設你為子類中引入的所有新屬性都提供了預設值,以下 2 個規則適用:

如果子類沒有定義任何指定構造器,它將自動繼承所有父類的指定構造器。

如果子類提供了所有父類指定構造器的實現——無論是通過規則 1 繼承過來的,還是提供了自定義實現——它將自動繼承所有父類的便利構造器。

//

示例1class

food

//便利構造器

convenience init()

}class

recipeingredient: food

//便利構造器

override

convenience init(name: string)

//重寫父類的便利構造器時,不需要加override關鍵字

convenience init()

}let onemysteryitem =recipeingredient();

let onebacon = recipeingredient(name: "

bacon");

let sixeggs = recipeingredient(name: "

eggs

", quantity: 6

);//

示例1說明:recipeingredient提供了父類的所有指定構造器的實現。因此,recipeingredient會自動繼承父類的所有便利構造器。

//示例2

class

shoppinglistitem: recipeingredient

}let item1 =shoppinglistitem();

let item2 = shoppinglistitem(name: "

bacon");

let item3 = shoppinglistitem(name: "

eggs

", quantity: 6

);//

示例2說明:shoppinglistitem為自己引入的所有屬性都提供了預設值,並且自己沒有定義任何構造器,shoppinglistitem將自動繼承所有父類中的指定構造器和便利構造器。

//

示例1:帶可失敗構造器的結構體

struct

animal

self.species =species;

}}let animal = animal(species: ""); //

nil//

示例2:帶可失敗構造器的列舉型別

enum

temperatureunit

}}let temperatureunit = temperatureunit(symbol: "

h"); //

nil//

示例3:帶原始值的列舉型別的可失敗構造器(等效於上面的temperatureunit)

//說明:帶原始值的列舉型別會自帶一個可失敗構造器init?(rawvalue:)

enum

temperatureunit2: character

let fahrenheitunit = temperatureunit2(rawvalue: "

h");

【說明】:也可以通過在init後面新增驚歎號的方式來定義一個可失敗構造器(init!)。不過,一旦init!構造失敗,則會觸發一個斷言。

class

someclass

}class

somesubclass: someclass

}