深入解析Swift编程中的构造方法

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

深⼊解析Swift编程中的构造⽅法
⼀、引⾔
构造⽅法是⼀个类创建对象最先也是必须调⽤的⽅法,在Objective-C中,开发者更习惯称这类⽅法为初始化⽅法。

在Objective-C中的初始化⽅法与普通函数相⽐除了要以init抬头外并⽆太严格的分界,⽽在Swift语⾔体系中,构造⽅法与普通的⽅法分界⼗分严格,从格式写法上就有不同,普通⽅法函数要以func声明,构造⽅法统⼀为init命名,不需要func关键字声明,不同的构造⽅法采⽤⽅法重载的⽅式创建。

⼆、构造⽅法的复写与重载
在Objective-C中,不同的初始化⽅法就是不同的函数,这便不存在⽅法重载的概念。

Swift中要创建⾃定义的构造⽅法,需要开发者对init构造⽅法进⾏重载操作。

任何⼀个⾃定义的类,只要其有⽗类,除了可以继承下来⽗类已有的构造⽅法外,还可以复写⽗类的构造⽅法,使其适⽤于⾃⾝。

和Objective-C类似,复写⽗类的构造⽅法时,要在其中调⽤⽗类的构造⽅法,重载可以理解为⼀种特殊的复写⽗类构造⽅法,因此在重载的构造⽅法中也要调⽤⽗类的构造⽅法。

创建⼀个继承于NSObject的类,复写构造⽅法,代码⽰例如下:
class ClassOne: NSObject {
//声明⼀个本类特有的常量
var tip:Int
//复写⽗类的构造⽅法需要⽤override关键字
override init() {
//构造⽅法中要对所有成员常量完成创建
tip = 1;
//在创建完所有成员常量后调⽤⽗类构造⽅法
super.init()
}
//重载构造⽅法1
init(one:Int){
tip=one
super.init()
}
//重载构造⽅法2 使⽤convenience关键字进⾏修饰
convenience init(two:String) {
//使⽤convenience关键字进⾏修饰的构造⽅法要调⽤本类的构造⽅法进⾏
self.init(one: two.characters.count)
}
//重载构造⽅法3 使⽤required关键字进⾏修饰使⽤required关键字进⾏修饰的构造⽅法⼦类必须继承或复写
required init(three:Float) {
tip=10
super.init()
}
上⾯⽰例代码中,不带参数的init()⽅法为复写⽗类的⽅法,因此需要使⽤关键字override来修饰。

重载构造⽅法1带⼀个Int类型的参数,⽗类中并没有这个构造⽅法,但是在其实现中,依然需要调⽤⽗类中的某个构造⽅法完成。

构造⽅法2是⼀个带String类型参数的构造⽅法,其⽤convenience关键字为构造⽅法的⼀个修饰关键字,后⾯会介绍。

构造⽅法3为⼀个带Float 类型参数的构造⽅法,但其使⽤required关键字进⾏了修饰,使⽤required关键字进⾏修饰的构造⽅法⼦类必须继承或者复写。

构造⽅法1,2,3都是对init()构造⽅法的⼀种重载,但却是3中类型全然不同的构造⽅法。

三、Designated构造⽅法与Convenience构造⽅法
Swift中的构造⽅法分为Designated构造⽅法与Convenience构造⽅法两类,Designated构造⽅法也被称为指定构造⽅
法,Convenience构造⽅法也被称为⽅便构造⽅法。

Designated构造⽅法不加任何修饰关键字,Convenience构造⽅法需要使⽤Convenience关键字进⾏修饰。

可以这样理解,Convenience类型的构造⽅法是为了⽅便使⽤从Designated构造⽅法中分⽀出来的构造⽅法,官⽅⽂档中有如下描述:
1.⼦类Designated构造⽅法中必须调⽤⽗类的Designated构造⽅法。

2.Convenience构造⽅法中必须调⽤当前类的构造⽅法。

3.Convenience构造⽅法归根结底要调⽤到Designated构造⽅法。

官⽅⽂档的⼀张图可以清晰的描述上述关系:
四、构造⽅法的继承关系
关于⼦类继承⽗类的构造⽅法有这样⼏个特性:
1.如果⼦类没有复写任何⽗类的构造⽅法,则默认⼦类将继承所有⽗类的构造⽅法,包括Designated构造⽅法与Convenience 构造⽅法。

2.如果⼦类复写了⽗类某⼀构造⽅法,则⼦类默认不在继承所有⽗类的构造⽅法,对于Designated类型的构造⽅法,⼦类复写了哪些,哪些才能够被使⽤,对于Convenienve类型的构造⽅法,⼦类复写的其调⽤的Designated构造⽅法后会被⾃动继承。

3.如果⽗类中的构造⽅法是required修饰的,则⼦类必须进⾏继承或复写。

曾经有朋友和我抱怨,Objective-C中的继承是⼀种⼗分不⼈性,它强制⼦类继承所有⽗类的⽅法与属性⽆论⼦类是否需要,分析上⾯的⼀些规则可以发现,Swift与Objective-C相⽐,在构造⽅法⽅⾯语法会更加严格,这样做在编程上更加安全。

在Objective-C中,⼦类将被强制继承所有⽗类的初始化⽅法,这样开发者在使⽤时常常会出现疑惑,有时⼀个⼦类往往有特定的初始化⽅法,仅仅通过⽗类的初始化⽅法不能够正确的完成初始化,在编程时,往往需要特殊注释来提⽰开发者。

Swift设定的这些构造⽅法原则可以将⽆关的⽗类构造⽅法剔除在外,在编程时更加严格安全,减少疑惑与不可控因素。

五、构造⽅法的实现原则
⽆论Designated类型的构造⽅法还是Convenience类型的构造⽅法,只要其有⽗类,最终都要实现⽗类的Designated构造⽅法。

Swift语⾔要求,在构造⽅法中要完成所有成员常量或者变量的构造或赋值(optional值除外)。

在对成员常量或变量进⾏构造赋值时,要在调⽤⽗类的初始化⽅法之前,这⾥还有⼀点需要注意,⽗类的成员属性也会被⼦类继承,如果要在⼦类复写的⽗类⽅法中对继承来的⽗类成员属性进⾏重新构造或赋值,则必须在调⽤⽗类构造⽅法之后,例如创建ClassTwo类继承于ClassOne,复写⽅法如下:
class ClassTwo: ClassOne {
//⼦类⾃⼰的属性
let tipTwo:Int
override init() {
//调⽤⽗类构造⽅法前进⾏⾃⼰属性的构造
tipTwo = 1
//调⽤⽗类构造⽅法
super.init()
//对从⽗类继承来的属性进⾏重构造
tip = 1000;
}
required init(three: Float) {
fatalError("init(three:) has not been implemented")
}
}
Swift语⾔这种强制化得构造规则,能够保证⼀个类在完成构造时,其内部的所有属性都构造完成。

在使⽤Objective-C进⾏开发时,很多初学者都可能会遇到这样⼀种情况,完成了某个类的初始化,但向类的属性进⾏赋值时却没有成功,因为Objective-C中并没有这样的语法,在类初始化成功后,其属性是否初始化了完全取决于开发者,Swift优化了这⼀设计。

综上可以了解,Swift语⾔虽然更加严格,却将更多本来需要开发者注意的地⽅交由了编译器,实际上是减轻了开发者的负担。

相关文档
最新文档