1、存儲屬性的初始賦值
init() {
// 在此處執(zhí)行構(gòu)造過程
}
//eg:
struct Fahrenheit {
var temperature: Double
init() {
temperature = 32.0
}
}
var f = Fahrenheit()
print("The default temperature is \(f.temperature)° Fahrenheit")
//The default temperature is 32.0° Fahrenheit
//你可以使用更簡單的方式在定義結(jié)構(gòu)體 Fahrenheit 時為屬性 temperature 設置默認值:
struct Fahrenheit1 {
var temperature = 32.0
}
2、自定義構(gòu)造過程
構(gòu)造參數(shù)
下面例子中定義了一個包含攝氏度溫度的結(jié)構(gòu)體 Celsius 。它定義了兩個不同的構(gòu)造器: init(fromFahrenheit:) 和 init(fromKelvin:) ,二者分別通過接受不同溫標下的溫度值來創(chuàng)建新的實例:
struct Celsius {
var temperatureInCelsius: Double
init(fromFahrenheit fahrenheit: Double) {
temperatureInCelsius = (fahrenheit - 32.0) / 1.8
}
init(fromKelvin kelvin: Double) {
temperatureInCelsius = kelvin - 273.15
} }
//自定義初始化
let boilingPointOfWater = Celsius(fromFahrenheit: 212.0)
// boilingPointOfWater.temperatureInCelsius 是 100.0
let freezingPointOfWater = Celsius(fromKelvin: 273.15)
// freezingPointOfWater.temperatureInCelsius 是 0.0
第一個構(gòu)造器擁有一個構(gòu)造參數(shù),其外部名字為 fromFahrenheit ,內(nèi)部名字為 fahrenheit ;
第二個構(gòu)造器也擁 有一個構(gòu)造參數(shù),其外部名字為 fromKelvin ,內(nèi)部名字為 kelvin
不帶外部名的構(gòu)造器參數(shù)
如果你不希望為構(gòu)造器的某個參數(shù)提供外部名字,你可以使用下劃線( _ )來顯式描述它的外部名,以此重寫上面所說的默認行為。
struct Celsius1 {
var temperatureInCelsius: Double
init(fromFahrenheit fahrenheit: Double) {
temperatureInCelsius = (fahrenheit - 32.0) / 1.8
}
init(fromKelvin kelvin: Double) {
temperatureInCelsius = kelvin - 273.15
}
init(_ celsius: Double){
temperatureInCelsius = celsius
}
}
let bodyTemperature = Celsius1(37.0)
// bodyTemperature.temperatureInCelsius 為 37.0
可選屬性類型
下面例子中定義了類 SurveyQuestion ,它包含一個可選字符串屬性 response
class SurveyQuestion {
var text: String
var response: String?//可選類型
init(text: String) {
self.text = text
}
func ask() {
print(text)
}
}
let cheeseQuestion = SurveyQuestion(text: "Do you like cheese?")
//調(diào)用函數(shù) ask() 方法
cheeseQuestion.ask()
// 打印 "Do you like cheese?"
cheeseQuestion.response = "Yes, I do like cheese."
構(gòu)造過程中常量屬性的修改
eg:
class SurveyQuestion1 {
let text: String //常量只被初始化一次
var response: String?
init(text: String) {
self.text = text
}
func ask() {
print(text)
} }
let beetsQuestion = SurveyQuestion1(text: "How about beets?")
beetsQuestion.ask()
// 打印 "How about beets?"
beetsQuestion.response = "I also like beets. (But not with cheese.)"
3、默認構(gòu)造器
如果結(jié)構(gòu)體或類的所有屬性都有默認值,同時沒有自定義的構(gòu)造器,那么 Swift 會給這些結(jié)構(gòu)體或類提供一個默 認構(gòu)造器(default initializers)。這個默認構(gòu)造器將簡單地創(chuàng)建一個所有屬性值都設置為默認值的實例。
下面例子中創(chuàng)建了一個類 ShoppingListItem ,它封裝了購物清單中的某一物品的屬性:名字( name )、數(shù)量( quantity )和購買狀態(tài) purchase state :
class ShoppingListItem {
var name: String?
var quantity = 1
var purchased = false
}
var item = ShoppingListItem()
print("name is \(item.name)")//name is nil
4、類的繼承和構(gòu)造過程
類里面的所有存儲型屬性——包括所有繼承自父類的屬性——都必須在構(gòu)造過程中設置初始值。
指定構(gòu)造器和便利構(gòu)造器
指定構(gòu)造器是類中最主要的構(gòu)造器。一個指定構(gòu)造器將初始化類中提供的所有屬性,并根據(jù)父類鏈往上調(diào)用父類的構(gòu)造器來實現(xiàn)父類的初始化
便利構(gòu)造器是類中比較次要的、輔助型的構(gòu)造器。你可以定義便利構(gòu)造器來調(diào)用同一個類中的指定構(gòu)造器,并為其參數(shù)提供默認值。你也可以定義便利構(gòu)造器來創(chuàng)建一個特殊用途或特定輸入值的實例
//指定構(gòu)造器和便利構(gòu)造器的語法
/*
init(parameters) {
statements
}
convenience init(parameters) {
statements
}
*/
類的構(gòu)造器代理規(guī)則
[? 指定構(gòu)造器必須總是向上代理
? 便利構(gòu)造器必須總是橫向代理]
構(gòu)造器的繼承和重寫
跟 Objective-C 中的子類不同,Swift 中的子類默認情況下不會繼承父類的構(gòu)造器。
Swift 的這種機制可以防止一個父類的簡單構(gòu)造器被一個更精細的子類繼承,并被錯誤地用來創(chuàng)建子類的實例。
重寫父類方法 要添加override 關(guān)鍵字
eg:
class Vehicle {
var numberOfWheels = 0
var description: String {
return "\(numberOfWheels) wheel(s)"
}
}
let vehicle = Vehicle()
print("Vehicle: \(vehicle.description)")
// Vehicle: 0 wheel(s)
//下面例子中定義了一個 Vehicle 的子類 Bicycle :
class Bicycle: Vehicle {
override init() {
super.init()
numberOfWheels = 2
}
}
let bicycle = Bicycle()
print("bicycle: \(bicycle.description)")
//bicycle: 2 wheel(s)
指定構(gòu)造器和便利構(gòu)造器實踐
class Food {
var name: String
init(name: String) {
self.name = name
}
convenience init() {
self.init(name: "[Unnamed]")
}
}
let namedMeat = Food(name: "Bacon")
// namedMeat 的名字是 "Bacon”
let mysteryMeat = Food()
// mysteryMeat 的名字是 [Unnamed]
class RecipeIngredient: Food {
var quantity: Int
init(name: String, quantity: Int) {
self.quantity = quantity
super.init(name: name)
}
override convenience init(name: String) {
self.init(name: name, quantity: 1)
}
}
let oneMysteryItem = RecipeIngredient()
let oneBacon = RecipeIngredient(name: "Bacon")
let sixEggs = RecipeIngredient(name: "Eggs", quantity: 6)
class ShoppingListItem1: RecipeIngredient {
var purchased = false
var description: String {
var output = "\(quantity) x \(name)"
output += purchased ? " ?" : " ?"
return output
}
}
var breakfastList = [
ShoppingListItem1(),
ShoppingListItem1(name: "Bacon"),
ShoppingListItem1(name: "Eggs", quantity: 6),
]
breakfastList[0].name = "Orange juice"
breakfastList[0].purchased = true
for item in breakfastList {
print(item.description)
}
// 1 x orange juice ?
// 1 x bacon ?
// 6 x eggs ?
可失敗構(gòu)造器
你可以在一個類,結(jié)構(gòu)體或是枚舉類型的定義中,添加一個或 多個可失敗構(gòu)造器。其語法為在 init 關(guān)鍵字后面添加問號( init? )
struct Animal {
let species: String
init?(species: String) {
if species.isEmpty { return nil }
self.species = species
}
}
你可以通過該可失敗構(gòu)造器來構(gòu)建一個 Animal 的實例,并檢查構(gòu)造過程是否成功:
let someCreature = Animal(species: "Giraffe") // someCreature 的類型是 Animal? 而不是 Animal
if let giraffe = someCreature {
print("An animal was initialized with a species of \(giraffe.species)")
}
// 打印 "An animal was initialized with a species of Giraffe"
let anonymousCreature = Animal(species: "")
// anonymousCreature 的類型是 Animal?, 而不是 Animal
if anonymousCreature == nil {
print("The anonymous creature could not be initialized")
}
// 打印 "The anonymous creature could not be initialized"
重寫一個可失敗構(gòu)造器
class Document {
var name: String?
// 該構(gòu)造器創(chuàng)建了一個 name 屬性的值為 nil 的 document 實例
init() {}
// 該構(gòu)造器創(chuàng)建了一個 name 屬性的值為非空字符串的 document 實例
init?(name: String) {
self.name = name
if name.isEmpty { return nil }
}
}
class AutomaticallyNamedDocument: Document {
override init() {
super.init()
self.name = "[Untitled]"
}
override init(name: String) {
super.init()
if name.isEmpty {
self.name = "[Untitled]"
} else {
self.name = name
}
}
}
這個子類重寫了父類的兩個指定構(gòu) 造器,確保了無論是使用 init() 構(gòu)造器,還是使用 init(name:) 構(gòu)造器并為參數(shù)傳遞空字符串,生成的實例中的 name 屬性總有初始 "[Untitled]
必要構(gòu)造器
//在類的構(gòu)造器前添加 required 修飾符表明所有該類的子類都必須實現(xiàn)該構(gòu)造器:
class SomeClass {
required init() {
// 構(gòu)造器的實現(xiàn)代碼
}
}
// 在重寫父類中必要的指定構(gòu)造器時,不需要添加 override 修飾符:
class SomeSubclass: SomeClass {
required init() {
// 構(gòu)造器的實現(xiàn)代碼
}
}