`

Swift构造器重载

 
阅读更多

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

[html] view plaincopy
 
  1. class Rectangle {  
  2.       
  3.     var width : Double  
  4.     var height : Double  
  5.       
  6.     init(width : Double, height : Double) { ①  
  7.         self.width   = width  
  8.         self.height  = height  
  9.     }  
  10.       
  11.     init(W width : Double,H height : Double) {  ②  
  12.         self.width   = width  
  13.         self.height  = height  
  14.     }  
  15.       
  16.     init(length : Double) { ③  
  17.         self.width   = length  
  18.         self.height  = length  
  19.     }  
  20.   
  21.   
  22.     init() {                        ④  
  23.         self.width   = 640.0  
  24.         self.height  = 940.0  
  25.     }  
  26.   
  27.   
  28. }  
  29.   
  30.   
  31. var rectc1 = Rectangle(width : 320.0, height : 480.0)   ⑤  
  32. println("长方形:\(rectc1.width) x \(rectc1.height)")  
  33.   
  34.   
  35. var rectc2 = Rectangle(W : 320.0, H : 480.0)    ⑥  
  36. println("长方形:\(rectc2.width) x \(rectc2.height)")  
  37.   
  38.   
  39. var rectc3 = Rectangle(length: 500.0)   ⑦  
  40. println("长方形3:\(rectc3.width) x \(rectc3.height)")  
  41.   
  42.   
  43. var rectc4 = Rectangle()    ⑧  
  44. println("长方形4:\(rectc4.width) x \(rectc4.height)")  



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

[html] view plaincopy
 
  1. struct Rectangle {  
  2.   
  3.   
  4.     var width : Double  
  5.     var height : Double  
  6.       
  7.     init(width : Double, height : Double) { ①  
  8.         self.width   = width  
  9.         self.height  = height  
  10.     }  
  11.       
  12.     init(W width : Double,H height : Double) {  ②  
  13.         self.width   = width  
  14.         self.height  = height  
  15.     }  
  16.       
  17.     init(length : Double) { ③  
  18.         self.init(W : length, H : length)  
  19.     }  
  20.   
  21.   
  22.     init() {                        ④  
  23.         self.init(width: 640.0, height: 940.0)  
  24.     }  
  25.   
  26.   
  27. }  
  28.   
  29.   
  30. var rectc1 = Rectangle(width : 320.0, height : 480.0)   ⑤  
  31. println("长方形:\(rectc1.width) x \(rectc1.height)")  
  32.   
  33.   
  34. var rectc2 = Rectangle(W : 320.0, H : 480.0)    ⑥  
  35. println("长方形:\(rectc2.width) x \(rectc2.height)")  
  36.   
  37.   
  38. var rectc3 = Rectangle(length: 500.0)   ⑦  
  39. println("长方形3:\(rectc3.width) x \(rectc3.height)")  
  40.   
  41.   
  42. var rectc4 = Rectangle()    ⑧  
  43. 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)。
由于我们还没有介绍继承,因此本章只介绍横向代理。
将上一节的示例修改如下:

[html] view plaincopy
 
  1. class Rectangle {  
  2.   
  3.   
  4.     var width : Double  
  5.     var height : Double  
  6.       
  7.     init(width : Double, height : Double) { ①  
  8.         self.width   = width  
  9.         self.height  = height  
  10.     }  
  11.       
  12.     init(W width : Double,H height : Double) {  ②  
  13.         self.width   = width  
  14.         self.height  = height  
  15.     }  
  16.       
  17.     convenience init(length : Double) { ③  
  18.         self.init(W : length, H : length)  
  19.     }  
  20.   
  21.   
  22.     convenience init() {    ④  
  23.         self.init(width: 640.0, height: 940.0)  
  24.     }  
  25.   
  26.   
  27. }  
  28.   
  29.   
  30. var rectc1 = Rectangle(width : 320.0, height : 480.0)   ⑤  
  31. println("长方形:\(rectc1.width) x \(rectc1.height)")  
  32.   
  33.   
  34. var rectc2 = Rectangle(W : 320.0, H : 480.0)    ⑥  
  35. println("长方形:\(rectc2.width) x \(rectc2.height)")  
  36.   
  37.   
  38. var rectc3 = Rectangle(length: 500.0)   ⑦  
  39. println("长方形3:\(rectc3.width) x \(rectc3.height)")  
  40.   
  41.   
  42. var rectc4 = Rectangle()    ⑧  
  43. 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课堂微信公共平台

分享到:
评论

相关推荐

    Swift学习笔记之构造器重载

    在Swift中,构造器重载的条件与函数重载类似,包括但不限于:函数名相同,但参数列表不同,或者返回值类型不同,或者外部参数名不同。对于构造器,我们可以根据参数数量、参数类型或参数的外部名称来实现重载。 在...

    (Swift)闭包构造函数

    1. **构造器闭包**:在Swift中,我们可以为类定义一个构造函数,这个构造函数可以接收一个闭包作为参数。这种闭包通常用于初始化过程中的复杂操作,例如设置默认值、执行副作用等。 2. **延迟初始化**:如果某个...

    swift 4.1 高清中文版PDF(cnswift.org翻译)

    - 结构体和类的初始化过程,包括指定构造器和便利构造器。 - 初始化器继承和重载,以及类型转换。 - 自动合成初始化器和默认成员初始值。 7. **高级运算符** (26_高级运算符.pdf): - 基本算术、比较和逻辑...

    Pro Swift-Break out of beginner’s Swift with this hands-on guide

    - **有用的初始化器**(Useful Initializers):介绍如何通过初始化器来构造对象或值类型,并探讨不同的初始化策略。 - **枚举**(Enums):强大的Swift特性之一,可以定义具有关联值的枚举类型,用于表示多种互斥...

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

    在Swift中,构造方法(或称为初始化器)使用`init`关键字声明,而不是像普通函数那样使用`func`。构造方法的重载是通过提供多个不同的`init`实现来完成的,每个实现可能带有不同的参数列表,以便在不同的情况下创建...

    Swift面试20问精解.docx

    这包括增加新的方法、属性、构造器等。扩展增强了Swift的模块化能力,使得代码更加整洁和易于维护。 #### 13. Swift中的泛型是什么? 泛型允许在定义函数、类或结构体时不预先指定具体的类型,而是在使用时指定。...

    Swifter - 100 个 Swift 必备 tips(免费)

    13. Designated,Convenience和Required:这三种是Swift中构造器的不同类型,用于在初始化过程中规定不同级别的初始化要求。 14. 编译标记:在Swift中,可以通过编译标记来控制编译行为。 15. @UIApplicationMain...

    Swift面试题.pdf

    Swift还支持其他一些高级特性,如网络请求和数据处理、自动引用计数(ARC)、模式匹配、扩展、异步操作、面向协议编程、高阶函数、调试和优化、函数式编程、数据持久化、枚举、多态、操作符重载、单例模式、延迟属性...

    10道常用的Swift面试题(附答案)

    - **Struct**的初始化基于属性,无需显式定义构造器。 ### Swift中的常量与Objective-C中的区别 - **Swift**中的常量(`let`)在运行时确定,而**Objective-C**中的常量(`const`)在编译期间就已确定。 ### 可选值与...

    Swift教程之继承详解

    与Objective-C不同,Swift的构造器重载需要手动处理,以保持初始化过程的正确性。 继承还包括方法的重写,即子类可以提供父类已有方法的新实现。Swift提供了`override`关键字来确保你明确地知道正在重写哪个方法。...

    IOS工程师,嵌入式,C,C++工程师,VC笔试题

    理解C++的构造函数、析构函数、拷贝构造函数和赋值运算符重载,以及如何实现深拷贝和浅拷贝,是C++工程师应具备的基本技能。 对于所有这些工程师职位,深入理解计算机体系结构、操作系统原理(如进程、线程、调度、...

    MVC源码学习:打造自己的MVC框架

    2.1、关于控制器工厂 ........................................................................................................................................... 32 2.2、控制器的父类实现 ..................

Global site tag (gtag.js) - Google Analytics