前端之家收集整理的这篇文章主要介绍了
Swift中构造方法的解析,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
Swift中构造方法的解析
一、引言
@H_
502_8@ 构造
方法是一个类创建对象最先也是必须
调用的
方法,在Objective-C中,开发者更习惯称这类
方法为初始化
方法。在Objective-C中的初始化
方法与普通
函数相比除了要以init抬头外并无太严格的分界,而在Swift语言体系中,构造
方法与普通的
方法分界十分严格,从格式写法上就有不同,普通
方法函数要以func声明,构造
方法统一为init命名,不需要func关键字声明,不同的构造
方法采用
方法重载的方式创建。
二、构造方法的复写与重载
@H_
502_8@ 在Objective-C中,不同的初始化
方法就是不同的
函数,这便不存在
方法重载的概念。Swift中要创建
自定义的构造
方法,需要开发者对init构造
方法进行重载操作。任何一个
自定义的类,只要其有
父类,除了可以继承下来
父类已有的构造
方法外,还可以复写
父类的构造
方法,使其适用于自身。和Objective-C类似,复写
父类的构造
方法时,要在其中
调用父类的构造
方法,重载可以理解为一种特殊的复写
父类构造
方法,因此在重载的构造
方法中也要
调用父类的构造
方法。
@H_
502_8@创建一个继承于NSObject的类,复写构造
方法,
代码示例如下:
- classClassOne:NSObject{
- //声明一个本类特有的常量
- vartip:Int
- //复写父类的构造方法需要用override关键字
- overrideinit(){
- //构造方法中要对所有成员常量完成创建
- tip=1;
- //在创建完所有成员常量后调用父类构造方法
- super.init()
- }
- //重载构造方法1
- init(one:Int){
- tip=one
- super.init()
- }
- //重载构造方法2使用convenience关键字进行修饰
- convenienceinit(two:String){
- //使用convenience关键字进行修饰的构造方法要调用本类的构造方法进行
- self.init(one:two.characters.count)
- }
- //重载构造方法3使用required关键字进行修饰使用required关键字进行修饰的构造方法子类必须继承或复写
- requiredinit(three:Float){
- tip=10
- super.init()
- }
@H_
502_8@上面示例
代码中,不带参数的init()
方法为复写
父类的
方法,因此需要使用关键字override来修饰。重载构造
方法1带一个Int类型的 参数,
父类中并没有这个构造
方法,但是在其实现中,依然需要
调用父类中的某个构造
方法完成。构造
方法2是一个带String类型参数的构造
方法,其用convenience关键字为构造
方法的一个修饰关键字,后面会介绍。构造
方法3为一个带Float类型参数的构造
方法,但其使用
required关键字进行了修饰,使用
required关键字进行修饰的构造
方法子类必须继承或者复写。构造
方法1,2,3都是对init()构造
方法的一种重载,但却是3中类型全然不同的构造
方法。
三、Designated构造方法与Convenience构造方法
@H_
502_8@ Swift中的构造
方法分为Designated构造
方法与Convenience构造
方法两类,Designated构造
方法也被称为指定构造
方法,Convenience构造
方法也被称为方便构造
方法。Designated构造
方法不加任何修饰关键字,Convenience构造
方法需要使用Convenience关键字进行修饰。可以这样理解,Convenience类型的构造
方法是为了方便使用从Designated构造
方法中分支出来的构造
方法,官方文档中有如下描述:
@H_
502_8@1.子类Designated构造
方法中必须
调用父类的Designated构造
方法。
@H_
502_8@2.Convenience构造
方法中必须
调用当前类的构造
方法。
@H_
502_8@3.Convenience构造
方法归根结底要
调用到Designated构造
方法。
@H_
502_8@官方文档的一张图可以清晰的描述上述关系:
四、构造方法的继承关系
@H_
502_8@关于子类继承
父类的构造
方法有这样几个特性:
@H_
502_8@1.如果子类没有复写任何
父类的构造
方法,则默认子类将继承所有
父类的构造
方法,
包括Designated构造
方法与Convenience构造
方法。
@H_
502_8@2.如果子类复写了
父类某一构造
方法,则子类默认不在继承所有
父类的构造
方法,对于Designated类型的构造
方法,子类复写了哪些,哪些才能够被使用,对于Convenienve类型的构造
方法,子类复写的其
调用的Designated构造
方法后会被
自动继承。
@H_
502_8@3.如果
父类中的构造
方法是
required修饰的,则子类必须进行继承或复写。
@H_
502_8@ 曾经有朋友和我抱怨,Objective-C中的继承是一种十分不人性,它强制子类继承所有
父类的
方法与
属性无论子类是否需要,分析上面的一些规则可以发现,Swift与Objective-C相比,在构造
方法方面语法会更加严格,这样做在编程上更加安全。在Objective-C中,子类将被强制继承所有
父类的初始化
方法,这样开发者在使用时常常会出现疑惑,有时一个子类往往有特定的初始化
方法,仅仅通过
父类的初始化
方法不能够正确的完成初始化,在编程时,往往需要特殊注释来
提示开发者。Swift设定的这些构造
方法原则可以将无关的
父类构造
方法剔除在外,在编程时更加严格安全,减少疑惑与不可控因素。
五、构造方法的实现原则
@H_
502_8@ 无论Designated类型的构造
方法还是Convenience类型的构造
方法,只要其有
父类,最终都要实现
父类的Designated构造
方法。Swift语言要求,在构造
方法中要完成所有成员常量或者变量的构造或赋值(optional值除外)。在对成员常量或变量进行构造赋值时,要在
调用父类的初始化
方法之前,这里还有一点需要注意,
父类的成员
属性也会被子类继承,如果要在子类复写的
父类方法中对继承来的
父类成员
属性进行重新构造或赋值,则必须在
调用父类构造
方法之后,例如创建ClassTwo类继承于ClassOne,复写
方法如下:
- classClassTwo:ClassOne{
- //子类自己的属性
- lettipTwo:Int
- overrideinit(){
- //调用父类构造方法前进行自己属性的构造
- tipTwo=1
- //调用父类构造方法
- super.init()
- //对从父类继承来的属性进行重构造
- tip=1000;
- }
-
- requiredinit(three:Float){
- fatalError("init(three:)hasnotbeenimplemented")
- }
-
-
- }
@H_
502_8@Swift语言这种强制化得构造规则,能够保证一个类在完成构造时,其内部的所有
属性都构造完成。在使用Objective-C进行开发时,很多初学者都可能会遇到这样一种情况,完成了某个类的初始化,但向类的
属性进行赋值时却没有成功,因为Objective-C中并没有这样的语法,在类初始化成功后,其
属性是否初始化了完全取决于开发者,Swift优化了这一设计。
@H_
502_8@ 综上可以了解,Swift语言虽然更加严格,却将更多本来需要开发者注意的地方交由了编译器,实际上是减轻了开发者的负担。
@H_502_8@专注技术,热爱生活,交流技术,也做朋友。
@H_502_8@——珲少 QQ群:203317592