与函数一样,方法也存在重载,其重载的方式与函数一致。那么作为构造器的特殊方法,是否也存在重载呢?答案是肯定的。
一、构造器重载概念
Swift中函数重载的条件也适用于构造器,条件如下:
函数有相同的名字;
参数列表不同或返回值类型不同,或外部参数名不同;
Swift中的构造器可以满足以下两个条件,代码如下:

  1. class Rectangle {
  2. var width : Double
  3. var height : Double
  4. init(width : Double, height : Double) { ①
  5. self.width   = width
  6. self.height  = height
  7. }
  8. init(W width : Double,H height : Double) {  ②
  9. self.width   = width
  10. self.height  = height
  11. }
  12. init(length : Double) { ③
  13. self.width   = length
  14. self.height  = length
  15. }
  16. init() {                        ④
  17. self.width   = 640.0
  18. self.height  = 940.0
  19. }
  20. }
  21. var rectc1 = Rectangle(width : 320.0, height : 480.0)   ⑤
  22. println("长方形:\(rectc1.width) x \(rectc1.height)")
  23. var rectc2 = Rectangle(W : 320.0, H : 480.0)    ⑥
  24. println("长方形:\(rectc2.width) x \(rectc2.height)")
  25. var rectc3 = Rectangle(length: 500.0)   ⑦
  26. println("长方形3:\(rectc3.width) x \(rectc3.height)")
  27. var rectc4 = Rectangle()    ⑧
  28. println("长方形4:\(rectc4.width) x \(rectc4.height)")

上述代码第①~④行定义了4个构造器,其他是重载关系。从参数个数和参数类型上看,第①行和第②行的构造器是一样的,但是它们的外部参数名不同,所以在第⑤行调用的是第①行的构造器,第⑥行调用的是第②行的构造器。
第③行和第④行的构造器参数个数与第①行不同,所以在第⑦行调用的是第③行的构造器,第④行调用的是第⑧行的构造器。
二、值类型构造器代理
为了减少多个构造器间的代码重复,在定义构造器时,可以通过调用其他构造器来完成实例的部分构造过程,这个过程称为构造器代理。构造器代理在值类型和引用类型中使用方式不同,本节我们先介绍值类型构造器代理。
将上一节的示例修改如下:

  1. struct Rectangle {
  2. var width : Double
  3. var height : Double
  4. init(width : Double, height : Double) { ①
  5. self.width   = width
  6. self.height  = height
  7. }
  8. init(W width : Double,H height : Double) {  ②
  9. self.width   = width
  10. self.height  = height
  11. }
  12. init(length : Double) { ③
  13. self.init(W : length, H : length)
  14. }
  15. init() {                        ④
  16. self.init(width: 640.0, height: 940.0)
  17. }
  18. }
  19. var rectc1 = Rectangle(width : 320.0, height : 480.0)   ⑤
  20. println("长方形:\(rectc1.width) x \(rectc1.height)")
  21. var rectc2 = Rectangle(W : 320.0, H : 480.0)    ⑥
  22. println("长方形:\(rectc2.width) x \(rectc2.height)")
  23. var rectc3 = Rectangle(length: 500.0)   ⑦
  24. println("长方形3:\(rectc3.width) x \(rectc3.height)")
  25. var rectc4 = Rectangle()    ⑧
  26. println("长方形4:\(rectc4.width) x \(rectc4.height)")

将Rectangle声明为结构体类型,其中也有4个构造器重载。在第③行和第④行的构造器中使用了self.init语句,self指示当前实例本身,init是本身的构造器,第③行的self.init(W : length, H : length)语句是在调用第②行定义的构造器,第④行的self.init(width: 640.0, height: 940.0)语句是在调用第①行定义的构造器。
这种在同一个类型中通过self.init语句进行调用就是我们说的构造器代理。
三、引用类型构造器横向代理
引用类型构造器代理就是类构造器代理。由于类有继承关系,类构造器代理比较复杂,分为横向代理和向上代理。
横向代理类似于值类型构造器代理,发生在同一类内部,这种构造器称为便利构造器(convenience initializers)。
向上代理发生在继承情况下,在子类构造过程中要先调用父类构造器,初始化父类的存储属性,这种构造器称为指定构造器(designated initializers)。
由于我们还没有介绍继承,因此本章只介绍横向代理。
将上一节的示例修改如下:

  1. class Rectangle {
  2. var width : Double
  3. var height : Double
  4. init(width : Double, height : Double) { ①
  5. self.width   = width
  6. self.height  = height
  7. }
  8. init(W width : Double,H height : Double) {  ②
  9. self.width   = width
  10. self.height  = height
  11. }
  12. convenience init(length : Double) { ③
  13. self.init(W : length, H : length)
  14. }
  15. convenience init() {    ④
  16. self.init(width: 640.0, height: 940.0)
  17. }
  18. }
  19. var rectc1 = Rectangle(width : 320.0, height : 480.0)   ⑤
  20. println("长方形:\(rectc1.width) x \(rectc1.height)")
  21. var rectc2 = Rectangle(W : 320.0, H : 480.0)    ⑥
  22. println("长方形:\(rectc2.width) x \(rectc2.height)")
  23. var rectc3 = Rectangle(length: 500.0)   ⑦
  24. println("长方形3:\(rectc3.width) x \(rectc3.height)")
  25. var rectc4 = Rectangle()    ⑧
  26. println("长方形4:\(rectc4.width) x \(rectc4.height)")

将Rectangle声明为类,其中也有4个构造器重载。在第③行和第④行的构造器中使用了self.init语句,并且在构造器前面加上了convenience关键字,convenience表示便利构造器,这说明我们定义构造器是横向代理调用其他构造器。

第③行的self.init(W : length, H : length)语句是在横向调用第②行定义的构造器代理,第④行的self.init(width: 640.0, height: 940.0)语句是在横向调用第①行定义的构造器代理。

更多内容请关注国内第一本Swift图书《Swift开发指南》
本书交流讨论网站:http://www.51work6.com/swift.php
欢迎加入Swift技术讨论群:362298485

欢迎关注智捷iOS课堂微信公共平台

最新文章

  1. RMAN异机恢复快速参考
  2. java中的泛型的使用与理解
  3. js基础3
  4. FFMpeg ver 20160213-git-588e2e3 滤镜中英文对照
  5. angularJ表单验证
  6. hdu2243考研路茫茫——单词情结(ac+二分矩阵)
  7. ASP.NET Razor——Razor 简介
  8. PAAS平台的web应用性能测试与分析
  9. C# 编程音量控制
  10. TextBlock 格式化内容
  11. css解决方案经验杂记
  12. MySQL与Oracle 差异比较之三函数
  13. C# 枚举绑定到ComboBox
  14. SpringMVC——hello SpringMVC
  15. C# - 转换
  16. php 随机显示据今天30天内的任意一天
  17. 每天一个Linux命令 6
  18. ecshop和jQuery冲突
  19. 【转】GPS误差来源
  20. day13(函数嵌套定义,global,nonlocal关键字,闭包,装饰器)

热门文章

  1. ADO.NET 快速入门(六):读写 XML
  2. Codeforces Gym 100610 Problem H. Horrible Truth 瞎搞
  3. ios开发——实用技术篇Swift篇&系统声音
  4. 日志分析(三) kibana数据展示
  5. 一天一个mysql函数(二) FIND_IN_SET()
  6. 非托管C++通过C++/CLI包装调用C# DLL
  7. 解析mysql索引
  8. 小白日记29:kali渗透测试之Web渗透-扫描工具-Vega
  9. Matrix 二维树状数组的第二类应用
  10. linux中的等待队列