Swift 构造器
Swift 的 构造过程和 OC 不一样,Swift 中构造方法没有返回值
Swift 中结构体和类的构造器有一些却别,结构体有默认构造器,类型没有默认构造器。
相同方法名的构造器,实参不一样则表示构造器也不一样
构造过程其实就是保证类或结构体中的存储属性完全初始化完成
实参:函数参数名
形参:函数内部使用的参数名
Swift 构造函数可以不带实参标签,用_
来表示,和函数一致
构造器可以对常量属性进行赋值(一次)
默认构造器(有自定义构造器将无法访问)
如果结构体或类的存储属性都已经有默认初始值,且没有提供自定义的构造器,那么会有一个默认的构造器init()
结构体的逐一成员构造器(有自定义构造器将无法访问)
结构体如果有存储属性没有默认初始值,且没有提供自定义构造器,那么会自动有一个逐一成员构造器,即,每个实参就是对应一个还没有默认值的存储属性
struct Size {
var width = 0.0, height = 0.0
}
let size = Size(width: 20, height: 20)
假如,需要同时存在 默认构造器、逐一成员构造器,自定义构造器都能使用,可以将自定义构造器放到extension拓展中。
值类型构造器代理
值类型没有继承,其构造器代理也相对简单,只要在自定义构造器中引用 同类型中的其他构造器。如调用 self.init()
struct Size {
var width = 0.0 , height = 0.0
}
struct Point {
var x = 0.0 , y = 0.0
}
struct Rect {
var point = Point()
var size = Size()
init() {}
init(point:Point, size: Size) {
self.point = point
self.size = size
}
init(center: Point, size: Size) {
let x = center.x - size.width/2
let y = center.y - size.height/2
self.init(point: Point(x: x, y: y), size: Size(width: 200, height: 200))
}
}
将自定义构造器移到 extentsion 中
struct Size {
var width = 0.0 , height = 0.0
}
struct Point {
var x = 0.0 , y = 0.0
}
struct Rect {
var point: Point
var size: Size
}
extension Rect {
init(center: Point, size: Size) {
let x = center.x - size.width/2
let y = center.y - size.height/2
self.init(point: Point(x: x, y: y), size: Size(width: 200, height: 200))
}
}
let rect2 = Rect(point: Point(x: 100, y: 100), size: Size(width: 200, height: 200))
let rect3 = Rect(center: Point(x: 100, y: 0), size: Size(width: 200, height: 200))
如果是直接放到结构体主体中,Xcode 会直接报错
struct Rect {
var point: Point
var size: Size
init(center: Point, size: Size) {
let x = center.x - size.width/2
let y = center.y - size.height/2
self.init(point: Point(x: x, y: y), size: Size(width: 200, height: 200))
}
}
类的构造过程
类因为有继承关系,所以类的构造过程比较复杂。
类类型中有几种构造器
-
便利构造器:
convenience
修饰的构造器 -
指定构造器 : 常规看到的构造器,不带修饰关键字的构造器
-
必要构造器:
required
修饰的构造器
必要构造器
子类必须实现的构造器,在子类实现必要构造器时,必须要在构造器前面也加 required
修饰,表明该构造器也用于继承链后面的子类,重写必要构造器时不需要 override
修饰
required init(parameters) {
statements
}
如果子类继承的构造器已经满足必要构造器的要求,则无需显示重写。如果子类没有定义任何指定构造器,则会自动继承父类所有指定构造器
便利构造器
构造器前面增加 convenience
修饰
convenience init(parameters) {
statements
}
指定构造器
指定构造器和结构体一样,普通的构造器写法
init(parameters) {
statements
}
类类型构造器的代理规则
-
指定构造器必须调用其父类的指定构造器
-
便利构造器必须调用该类定义的其他构造器
-
便利构造器最后必须调用指定构造器
指定构造器必须向上代理
便利构造器必须要横向代理
这样就可以保证构造其能构完全的初始化实例
构造器的自动继承
假设已经为子类中引入的所有新属性都提供了默认值,以下 2 个规则将适用:
-
如果子类没有定义任何指定构造器,它将自动继承父类所有的指定构造器。
-
如果子类提供了所有父类指定构造器的实现——无论是通过规则 1 继承过来的,还是提供了自定义实现——它将自动继承父类所有的便利构造器。
子类可以将父类的指定构造器实现为便利构造器来满足规则 2。
可失败构造器
可失败构造器是 类似可选值的写法,构造过程在特定条件下返回会 nil,子类重写可失败构造器,可以将其重写为不可失败构造器,反之不行。
init?(parameters) {
if 条件为 true {
return nil
}
statements
}
可失败构造器的参数名和参数类型,不能与不可失败构造器相同
原文始发于微信公众号(三万之一):Swift 中的初始化:init
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/231271.html