1.指定构造和便利构造方法解析
这些是类类型的概念,在值类型里没有
class Ab {
var a: Int
var b: Int
//以init开头就是指定构造
init(a: Int,b: Int){
self.a = a
self.b = b//注意:类的指定构造方法里不能像值类型那样调用其他构造器
print("Class ab init")
}
//类似值类型的构造方法,加上关键字convenience,搭配self.init就是便利构造方法,他通过调用其他的构造方法来实现初始化,当然既可以通过指定构造方法也可以是其他便利构造方法
convenience init(a: Int){
// self.a = a
// b = 0
self.init(a: a,b: 0)
}
}
2.派生类的构造方法
class Ab {
var a: Int
var b: Int
//以init开头就是指定构造
init(a: Int,b: Int){
self.a = a
self.b = b//注意:类的指定构造方法里不能像值类型那样调用其他构造器
print("Class ab init")
}
//类似值类型的构造方法,加上关键字convenience,搭配self.init就是便利构造方法,他通过调用其他的构造方法来实现初始化,当然既可以通过指定构造方法也可以是其他便利构造方法
convenience init(a: Int){
// self.a = a
// b = 0
self.init(a: a,b: 0)
}
}
class CD: Ab {
var c: Int
var d: Int
//构造方法默认是不会被继承,基类的存储属性只能通过基类的构造方法来初始化。
//派生类引入的存储属性要先被初始化,然后在调用父类的构造方法对父类的属性进行初始化
//我们只能通过调用父类的指定构造方法来对父类的属性进行初始化
init(c: Int,d: Int){//指定构造器
self.c = c
self.d = d
super.init(a: 1, b: 1)//通过父类指定构造方法来初始化
}
}
3.构造器链
//指定构造器必须调用其直接父类的指定构造器
//便利构造器必须调用同类中定义的其他构造器(指定,便利)
//便利构造器必须最终以调用一个指定构造器结束。
4.两段式构造--构造过程可以划分为两个阶段:
第一,确保所有的存储属性都初始化完毕
第二,对父类中的存储属性做进一步的处理,可以防止属性在被初始化之前访问,也可以防止属性被另外一个构造器意外的赋值
class A {
var a: Int
init(a: Int){
self.a = a
}
}
class B: A{
var b: Int
init (a: Int,b: Int){
//派生类引入的属性进行初始化
print(";b类第一阶段初始化开始")
self.b = b//先初始化当前类的属性
//再用父类的指定构造方法对父类的属性进行初始化
super.init(a: a)
//额外的代码执行
print("b类第二阶段初始化开始")
if(b>100){
self.a = 100
}
}
}
5.派生类构造方法定义时的编译器安全性检查
首先应该将派生类引入的存储属性初始化,再向上代理父类的指定构造方法
首先调用父类的指定构造器实现父类中属性的初始化之后,才可以访问父类的属性
在便利构造器,首先调用同类中的其他构造方法,才可以访问属性
在第一阶段完成之前,不能调用任何实例方法,不能访问任何父类中的存储属性,不能引用self
6.重写指定构造方法
是指子类构造方法与父类构造方法的参数列表一样
class Human {
let name: String
var age: Int
init (name: String,age: Int){
self.name = name
self.age = age
}
}
class Woman: Human {
let haveBaby: Bool
//派生类定义一个指定构造方法去覆盖父类中与他有相同参数列表的指定构造方法
// override init(name: String, age: Int) {
// haveBaby = false
// super.init(name: name, age: age)
// }
//也可以定义指定构造方法,引出便利构造方法,用便利构造器覆盖
init(name: String, age: Int,haveBaby: Bool) {
self.haveBaby = haveBaby
super.init(name: name, age: age)
}
override convenience init(name: String, age: Int) {
self.init(name: name,age: age,haveBaby: false)
}
}
7.构造方法的自动继承
a.如果子类中没有定义任何的构造方法,且子类中所有的存储属性都有默认缺省值,会自动继承父类中所有的构造方法,包括便利构造方法.但是子类中有自己定义的构造方法则不会继承父类的任何构造方法
b。如果子类中只是重写了父类中的某些(而不是全部)指定构造方法,不管子类中的存储属性是否有缺省值,都不会继承父类中的其他构造方法
c。如果子类中重写了父类中所有的指定构造方法,不管子类中的存储属性是否有缺省值,都同时会继承父类中所有的便利构造方法
class xy {
var x: Int
var y: Int
init(x: Int,y: Int){
self.x = x
self.y = y
}
convenience init(){
self.init(x:0,y:0)
}
}
class xyz: xy {
var z: Int = 10
// init(z: Int){
// self.z = z
// super.init(x: 0, y: 0)
// }//一旦定义自己的构造方法,则不能继承父类的构造方法
}
var r1 = xyz()
var r2 = xyz(x: 2, y: 2)//当xyz类中没有任何构造方法时,且自己的存储属性有缺省值时,就能继承父类的构造方法
8.必须构造器
构造方法所属的类的后续子子孙孙类必须实现这个构造方法
class Some {
var some: Int
required init(){
some = 0
}
}
class Subsome: Some {
var sub: Int
init(sub: Int){
self.sub = sub
super.init()
}
required init() {//required必须得写
sub = 0
super.init()
}
}
class Subsubsome: Subsome {
required init() {
super.init()
}
}
来源:oschina
链接:https://my.oschina.net/u/2598427/blog/636246