Swift 中类的初始化器与继承
首先,Swift 为类定义了两种初始化器来确保类中所有的储存属性都能得到一个初始化值。这两种初始化器就是「指定初始化器」(Designated Initializer)与「便利初始化器」(Convenience Initializer)。
指定初始化器与便利初始化器
指定初始化器是类的最主要的初始化器,它会将类中所有的属性赋值初始化,并且一路往上调用类的父类的指定初始化器去初始化它们各自引入的属性。类可以有许多个指定初始化器,也可以只有一个,但必须至少有一个。
便利初始化器顾名思义就是方便开发者调用的初始化器,它必须调用同个类的指定初始化器,提供一些默认的参数给指定初始化器来生成一个默认的类的实例。一个类可以没有便利初始化器。
初始化器链
为了简化指定初始化器与便利初始化器的关系,我们规定了以下三条规则:
指定初始化器必须调用其父类的指定初始化器
便利初始化器初始化器必须调用该类中另一个初始化器
便利初始化器最终必须调用一个指定初始化器
简单的说,就是指定初始化器必须在类的继承关系中一路向上调用,便利初始化器必须在该类中一路往指定初始化器调用。
画成图表表示,就是:
上图可以看到,父类有一个指定初始化器和两个便利初始化器,一个便利初始化器调用了另一个遍历初始化器,但最终他们都会调用指定初始化器。
而在子类中,指定初始化器最终是向上,调用其父类的指定初始化器。
初始化的两个步骤
在 Swift 中,类的初始化需要经历两个步骤,第一个步骤中,每一个该类引入的储存属性都需要给赋上一个初始值。完成后,执行第二个步骤,每个类都可以再对属性进行自定义修改。
详细点说,即是:
步骤一
一个类的指定或便利初始化器需被调用
类的实例的内存被申请,但还没有初始化
指定初始化器确保当前类引入的所有储存属性都初始化
指定初始化器调用其父类的指定初始化器,继续让父类去初始化它所引入的储存属性
上面这个过程一直进行直到最终的根类的指定初始化器被调用
当根类的指定初始化器调用后,该类的实例就已经确保了所有储存属性都已经初始化完成,步骤一完成。
步骤二
步骤二是从根类的指定初始化器开始的,一层层到最终的子类的指定初始化器
在这个步骤中,每个类都有机会对已经步骤一中初始化完成的实例再次进行自定义修改。此时初始化器已经可以访问 self,修改属性或者调用实例方法了。
初始化器的继承与覆盖
不像 Objective-C,Swift 的类并不会默认继承其父类的初始化器。但也有例外,只要满足了一定条件,子类还是会自动继承父类的初始化器的。我们定义了以下规则:
规则一
如果你的子类没有定义任何指定初始化器,则其会自动继承其父类的所有指定初始化器
规则二
如果你的子类实现了其父类的所有指定初始化器,不管是自定义的实现还是因为规则一造成的实现,该子类自动继承其父类所有的便利初始化器。
与 Objective-C 的初始化器交互
Swift 调用 Objective-C 的类,其初始化方法自动省去"Init"或"InitWith"关键字。比如
1
2
3
4
|
//Objective-C UILabel *label = [UILabel alloc] init]; UITableView *myTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped]; |
在 Swift 中,写成
1
2
3
4
|
//Swift let label: UILabel = UILabel() let myTableView: UITableView = UITableView(frame: CGRectZero, style: .Grouped) |
你也不需要调用 alloc,Swift 会帮你搞定这步的。
另外,某些 Objective-C 中方便的用于类的初始化的工厂方法,也映射到了 Swift 中,比如
1
2
|
//Objective-C UIColor *color = [UIColor colorWithRed:0.5 green:0.0 blue:0.5 alpha:1.0]; |
在Swift中:
1
2
|
//Swift let color = UIColor(red: 0.5, green: 0.0, blue: 0.5, alpha: 1.0) |
Swift 中类的初始化器与继承的更多相关文章
- Swift中类的初始化器与继承
初始化是类,结构体和枚举类型实例化的准备阶段.这个阶段设置这个实例存储的属性的初始化数值和做一些使用实例之前的准备以及必须要做的其他一些设置工作. 通过定义构造器(initializers)实现这个实 ...
- 6.Swift协议|扩展|访问权限|异常调试|类型转换|运算函数|ARC|类类型初试化器|值类型初始化器
1. 协议(Protocol):与OC之间唯一不同的是Swift中的协议不管是属性还时方法全部是必须实现的 /** protocol*/ protocol FullNamed { /** 计算属性申明 ...
- Swift中类与结构的初始化
前言:通过学习与研究swift3.0的官方文档关于初始化这部分可以总结为一句话:类与结构是确保一个类型的实例可以使用之前,其所有存储属性都得到了正确的赋值. 一,结构的初始化1 struct Firs ...
- Swift快速给Cocoa库内置类添加便捷初始化器
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) Cocoa中的NSShadow类默认没有我们需要的实例方法,为 ...
- swift 学习- 17 -- 析构器
// 析构器 只适用与 类类型, 当一个类的实例被释放之前, 析构器会被立即调用, 析构器用关键字 deinit 来标示, 类似于构造器要用 init 来标示 // 析构过程原理 // Swift 会 ...
- Swift 学习笔记 (初始化)
初始化是为类 结构体 或者枚举准备实例的过程.这个过程需要给实例里的每一个存储属性设置一个初始值并且在新实例可以使用之前执行任何其它所必需的配置或初始化. 初始化器 初始化器在创建特定类型的实例时被调 ...
- Swift中类的使用
主要内容 类的介绍和定义 类的属性 类的构造函数 一. 类的介绍和定义 Swift也是一门面向对象开发的语言 面向对象的基础是类,类产生了对象 在Swift中如何定义类呢? class是Swift中的 ...
- java中类的初始化和对象的初始化
静态的属于全局静态区,这个部分独立存在,不管是成员还是块,都是静态的,大家地位相等,先到先得. 然后是成员初始化,这个部分在类的构造函数前初始化,因为编译器(或者设计者)可能认为构造函数调用了这个成员 ...
- swift_初始化器的使用
//: Playground - noun: a place where people can play import Cocoa ***************************结构体与Cla ...
随机推荐
- codeforces 8C. Looking for Order 状压dp
题目链接 给n个物品的坐标, 和一个包裹的位置, 包裹不能移动. 每次最多可以拿两个物品, 然后将它们放到包里, 求将所有物品放到包里所需走的最小路程. 直接状压dp就好了. #include < ...
- svn 同步到web目录
windows hook 下 @echo offSET REPOS=%1SET REV=%2SET DIR=%REPOS%/hooksSET PATH=%PATH%;SET WORKING=D:/w ...
- Android中ViewStub组件使用
1. 概述: ViewStub组件和<include>标签的作用类似,主要是为了提高布局的重用性,及布局的模块化.它们之间最大的差别是,ViewStub中的布局不会随着它所在布局的渲染而渲 ...
- python-模块系列
--> 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能 ...
- EF(ServerFirst)执行存储过程实例1(带输出参数)
1.不含动态sql.带输出参数存储过程调用实例 a.存储过程代码: b.EF自动生成代码(包括对应ObjectResult的实体模型): c.调用存储过程代码实例: 总结: ObjectParame ...
- Mock.js 与 fiddler 前端模拟数据与拦截请求
最近 工作需要 接触了Mock.js. Mock.js 是一款模拟数据生成器,旨在帮助前端攻城师独立于后端进行开发,帮助编写单元测试.提供了以下模拟功能: 根据数据模板生成模拟数据 模拟 Ajax ...
- Excel几个常用操作
1.冻结第一行:视图->冻结窗格->冻结首行 2.第一行自动筛选:选择要设置的行,数据->筛选->自动筛选 3.在单元格中添加下拉菜单:(1)选中一列,数据->数据验证. ...
- onclick=‘’return false“
文章来自 http://www.cnblogs.com/hellen-li/archive/2010/10/22/1858422.html checkbox没有readOnly属性,可以这样让它保持 ...
- inline函数和一般的函数有什么不同
1.比如: int g(int x) { return x + x; } int f() { return g(); } 这样f会调用g,然后g返回x + x给f,然后f继续把那个值返回给调用者. 如 ...
- KVC中setValuesForKeysWithDictionary:
本文转载于:http://my.oschina.net/u/2407613/blog/524879?p={{page}} 从字典映射到一个对象,这是KVC中的一个方法所提供的,这个方法就是 setVa ...