构造器
构造器在创建某个特定类型的新实例时被调用。它的最简形式类似于一个不带任何参数的实例方法,以关键字init命名
init() {
// 在此处执行构造过程
}
结构体构造过程
构造参数
struct Person {
var age:Int
var name:String = "LouKit" //默认属性值
init(fromMan pAge:Int) {
age = pAge + 1;
}
init(fromWomen pAge:Int) {
age = pAge + 2;
}
}
let mAge = Person(fromMan:80)
let wAge = Person(fromWomen:80)
print("\(mAge.age)--\(wAge.age)-")//81 82
struct Color {
let red,green,blue: Double
init(red: Double,green: Double,blue: Double) {
self.red = red
self.green = green
self.blue = blue
}
init(white: Double) {
red = white
green = white
blue = white
}
}
let magenta = Color(red: 1.0,green: 0.0,blue: 1.0)
let halfGray = Color(white: 0.5)
不带外部名的构造器参数
struct Color {
let red,blue: 1.0)
let halfGray = Color(white: 0.5)
结构体拥有逐一成员构造器
struct Size {
var width = 0.0,height = 0.0
}
let twoByTwo = Size(width: 2.0,height: 2.0)
类的继承和构造过程
Swift 编译器将执行 4 种有效的安全检查,以确保两段式构造过程能不出错地完成:
安全检查 1
指定构造器必须保证它所在类引入的所有属性都必须先初始化完成,之后才能将其它构造任务向上代理给父类中的构造器。
如上所述,一个对象的内存只有在其所有存储型属性确定之后才能完全初始化。为了满足这一规则,指定构造器必须保证它所在类引入的属性在它往上代理之前先完成初始化。
安全检查 2
指定构造器必须先向上代理调用父类构造器,然后再为继承的属性设置新值。如果没这么做,指定构造器赋予的新值将被父类中的构造器所覆盖。
安全检查 3
便利构造器必须先代理调用同一类中的其它构造器,然后再为任意属性赋新值。如果没这么做,便利构造器赋予的新值将被同一类中其它指定构造器所覆盖。
安全检查 4
构造器在第一阶段构造完成之前,不能调用任何实例方法,不能读取任何实例属性的值,不能引用self作为一个值。
类实例在第一阶段结束以前并不是完全有效的。只有第一阶段完成后,该实例才会成为有效实例,才能访问属性和调用方法。
总结: 先全部初始化好自己的属性,然后才能调用父类的构造器;便利构造器只能调用同一类的指定构造器
构造器的自动继承
假设你为子类中引入的所有新属性都提供了默认值,以下 2 个规则适用:
规则 1
如果子类没有定义任何指定构造器,它将自动继承所有父类的指定构造器。
规则 2
如果子类提供了所有父类指定构造器的实现——无论是通过规则 1 继承过来的,还是提供了自定义实现——它将自动继承所有父类的便利构造器.(子类可以将父类的指定构造器实现为便利构造器)
类型转换
is
用类型检查操作符(is)来检查一个实例是否属于特定子类型。若实例属于那个子类型,类型检查操作符返回 true,否则返回 false。
向下转型 as?/as!
转型有可能失败时选用as?,如果失败就是为nil
如果能保证一定能转型成功as!,但如果失败程序直接报运行时错
Any 和 AnyObject 的类型转换