Swift学习笔记(六)继承、构造、析构

1. 继承
①基类
Swift 中的类并不是从一个通用的基类继承而来。不继承于其它类的类,称之为基类。
②子类
[c]
class SomeClass: SomeSuperclass {
// 这里是子类的定义
}
[/c]
③重写
重写方法
[c]
class Train: Vehicle {
override func makeNoise() {
print("Choo Choo")
}
}
[/c]
重写属性
[c]
class Car: Vehicle {
var gear = 1
override var description: String {
return super.description + " in gear \(gear)"
}
}
[/c]
重写属性观察器
[c]
class AutomaticCar: Car {
override var currentSpeed: Double {
didSet {
gear = Int(currentSpeed / 10.0) + 1
}
}
}
[/c]
※你不可以为继承来的常量存储型属性或继承来的只读计算型属性添加属性观察器。
※你不可以同时提供重写的 setter 和重写的属性观察器。
④防止重写
你可以通过把方法,属性或下标标记为final来防止它们被重写,只需要在声明关键字前加上final修饰符即可(例如:final var,final func,final class func,以及final subscript)。
2. 构造过程
Swift 的构造器保证新实例在第一次使用前完成正确的初始化。
①存储属性的初始赋值
构造器
[c]
init() {
// 在此处执行构造过程
}
[/c]
②自定义构造过程
构造参数
自定义构造过程时,可以在定义中提供构造参数,指定所需值的类型和名字。构造参数的功能和语法跟函数和方法的参数相同。
参数的内部名称和外部名称
如果你在定义构造器时没有提供参数的外部名字,Swift 会为构造器的每个参数自动生成一个跟内部名字相同的外部名。
不带外部名的构造器参数
如果你不希望为构造器的某个参数提供外部名字,你可以使用下划线(_)来显式描述它的外部名,以此重写上面所说的默认行为。
可选属性类型
可选类型的属性将自动初始化为nil,表示这个属性是有意在初始化时设置为空的。
构造过程中常量属性的修改
你可以在构造过程中的任意时间点给常量属性指定一个值,只要在构造过程结束时是一个确定的值。一旦常量属性被赋值,它将永远不可更改。
默认构造器
如果结构体或类的所有属性都有默认值,同时没有自定义的构造器,那么 Swift 会给这些结构体或类提供一个默认构造器(default initializers)。这个默认构造器将简单地创建一个所有属性值都设置为默认值的实例。
逐一成员构造器
除了上面提到的默认构造器,如果结构体没有提供自定义的构造器,它们将自动获得一个逐一成员构造器,即使结构体的存储型属性没有默认值。
[c]
struct Size {
var width = 0.0, height = 0.0
}
let twoByTwo = Size(width: 2.0, height: 2.0)
[/c]
值类型的构造器代理
构造器可以通过调用其它构造器来完成实例的部分构造过程。这一过程称为构造器代理,它能减少多个构造器间的代码重复。
③类的继承和构造过程
指定构造器和便利构造器
指定构造器
[c]
init(parameters) {
statements
}
[/c]
便利构造器
[c]
convenience init(parameters) {
statements
}
[/c]
类的构造器代理规则
为了简化指定构造器和便利构造器之间的调用关系,Swift 采用以下三条规则来限制构造器之间的代理调用:
规则 1
指定构造器必须调用其直接父类的的指定构造器。
规则 2
便利构造器必须调用同类中定义的其它构造器。
规则 3
便利构造器必须最终导致一个指定构造器被调用。
一个更方便记忆的方法是:
指定构造器必须总是向上代理
便利构造器必须总是横向代理

两段式构造过程
阶段 1
某个指定构造器或便利构造器被调用。
完成新实例内存的分配,但此时内存还没有被初始化。
指定构造器确保其所在类引入的所有存储型属性都已赋初值。存储型属性所属的内存完成初始化。
指定构造器将调用父类的构造器,完成父类属性的初始化。
这个调用父类构造器的过程沿着构造器链一直往上执行,直到到达构造器链的最顶部。
当到达了构造器链最顶部,且已确保所有实例包含的存储型属性都已经赋值,这个实例的内存被认为已经完全初始化。此时阶段 1 完成。
阶段 2
从顶部构造器链一直往下,每个构造器链中类的指定构造器都有机会进一步定制实例。构造器此时可以访问self、修改它的属性并调用实例方法等等。
最终,任意构造器链中的便利构造器可以有机会定制实例和使用self。
构造器的继承和重写