Swift(九) 构造方法/析构方法

构造方法(Initialization)

Swift 中构造方法无需返回值,系统默认实现返回self。

Swift初始化方法需要保证类型的所有属性都被初始化

1
2
3
init() {
// 在此处执行构造过程
}

构造参数

1
2
3
4
5
6
7
8
9
10
11
12
13
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”

可选属性类型

可选类型在声明的时候默认为nil

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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?")
cheeseQuestion.ask()
// 输出 "Do you like cheese?"
cheeseQuestion.response = "Yes, I do like cheese."

构造过程中常量属性的修改

可以在构造函数中修改常量属性的值,一旦赋值,将不可更改

默认构造器

结构体的逐一成员构造器

值类型的构造器代理

构造器可以通过调用其它构造器来完成实例的部分构造过程。这一过程称为构造器代理,它能减少多个构造器间的代码重复。

如果为值类型构造器自定义了一个构造器,将不能使用默认构造器(结构体将不能使用逐一构造器)

如果想使用?把自定义构造器写在扩展中。

类的继承和构造过程

子类完成初始化必须调用父类初始化方法

指定构造器和便利构造器

1
2
3
init(parameters) {
statements
}
1
2
3
convenience init(parameters) {
statements
}

类的构造器代理规则

  • 指定构造器必须向上代理

  • 遍历构造器必须横向代理

构造器继承和重写

“在某个类的子类中,初始化方法里语句的顺序并不是随意的,我们需要保证在当前子类实例的成员初始化完成后才能调用父类的初始化方法:”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Cat {
var name: String
init() {
name = "cat"
}
}

class Tiger: Cat {
let power: Int
override init() {
power = 10 // 1. 设置子类自己需要初始化的参数
super.init() // 2. 调用父类初始化方法
name = "tiger" // 3. 对父类需要改变的成员赋值 如果不需要改变的话 就不需要2.3 部 swift会自动调用父类init方法
}
}

可失败构造器

类、结构体、枚举在构造过程中可能失败,如传入参数不符合要求。

为了处理这种构造过程中可能出现的失败的情况,可以在类、结构体、枚举中添加一个或多个可失败的构造器,init?

1
2
3
4
5
6
7
struct Animal {
let species: String
init?(species: String) {
if species.isEmpty { return nil } // return nil 表明构造失败
self.species = species
}
}

必要构造器

1
2
3
4
5
6
7
8
9
10
11
12
class SomeClass {
required init() {
// 构造器的实现代码
}
}

class SomeSubclass: SomeClass {
// 不需要写override
required init() {
// 构造器的实现代码
}
}