扩展
Swift中的扩展,对应OC中的分类,可以用它来拓展类的功能。
可以扩展类的什么:
添加新的属性(只能是计算型属性),且也不能为已有的属性添加属性观察器;
添加新方法(实例方法和类方法);
添加新的构造器(只是便利构造器);
甚至还可以在该扩展中使该类符合某个协议,即申明该类遵守某个协议。
注意:
扩展仅可以为类添加新的功能,但不能重写该类原有的方法等。
某类的扩展是可以访问该类的属性方法的。
扩展语法:
extension Int
就表示这是对Int
类型的扩展。
extension Int {
var numStr: String {
get{
return "\(self)次"
}
}
func printTheNum() {
print(numStr)
}
func repeats(task: ()->Void) {
for _ in 0..<self {
task()
}
}
}
在Int
的扩展中,我们首先为Int
添加了只读计算型属性numStr
,它是以该Int
型的数值拼接成的字符串。然后又新添了两个方法。printTheNum()
方法的功能是打印numStr
属性。repeats(task:)
方法有一个参数task
,其类型为()->Void
,即没有参数没有返回值的闭包!传入该方法的闭包将会被执行该数值次。
调用:
let num = 2
num.printTheNum() // log:2次
num.repeats {
print("i am your man")
}
// log: i am your man
// i am your man
可变实例方法:
如果在扩展中新添的方法修改了self
或者self
的属性,则必须以关键字mutating
标注。
mutating func squre() {
self = self*self
}
泛型:
什么是泛型?
通俗说一下,就是一个函数,或者类,使用到某个(或多个)参数,这个参数的类型,在设计期间是可供多选的,那么这个函数(类),就称作泛型函数(泛型类)。
泛型约束:
泛型约束就是指定这个泛型使用到的可选类型的选择范围——也就是说指定它必须有的某些特征,因为泛型函数(泛型类)里需要用到这些特征,所以调用方使用泛型时候,指定的可选参数类型也必须具有这些特征。
数字和字典这些集合类就是典型的“泛型”,这些集合可以存放很多类型的数据。如果没有泛型,那想象一下,我们得定义多少种数组初始化的方式。
协议:
协议是什么无需再做解释,直接来看Swift中它的语法:
协议语法:
protocol SomProtocol {
// 这里是协议要定义的东西
}
在Swift中表示类实现协议和继承是一样的,都用冒号:
,若实现多个协议则多个协议之间同样也用逗号隔开。
当一个类既有继承父类,又实现了某协议时。规定冒号后面先是继承的类,然后才是实现的协议。
下面的代码定义了一个StaffModel
类,它继承于UserModel
,并且还实现了两个协议SomProtocol
,OtherProtocol
。
class StaffModel: UserModel, SomProtocol, OtherProtocol {
}
属性要求:
协议中可以定义对所遵守该协议的类中属性的要求。可以要求属性的类型、名字,以及可读还是可写。
下面定义的协议SomProtocol
中定义了所遵守该协议的类中属性的要求。必须要有个叫fullName
的,字符串类型的,可读可写的属性。
protocol SomProtocol {
var fullName: String {get set}
}
方法要求:
协议中定义对方法的要求。只有方法的定义,没有对应的方法体。
protocol SomProtocol {
var fullName: String {get set}
func nameHandle(fullName: String) -> String
}
构造器要求:
协议中也可以定义对构造器的要求。基本和定义方法是一样。但是在实现该协议的类中实现该构造器时,无论在类中是作为指定构造器还是便利构造器,都要在前面加上required
关键字。
protocol SomProtocol {
var fullName: String {get set}
init(fullName: String)
func nameHandle(fullName: String) -> String
}
class StaffModel: UserModel, SomProtocol {
var fullName: String = "" // SomProtocol协议要求的属性
required init(fullName: String) { // 协议要求的构造器
self.fullName = fullName
super.init()
}
func nameHandle(fullName: String) -> String { // 协议要求的方法
return "fullName:\(fullName)"
}
}
协议可以作为类型
协议可以作为变/常量、属性、方法参数、集合类元素的类型。表示实现了该协议的任何一种实例。
通过协议实现协议
有时不方便在原类中实现协议,那我们通过扩展来实现协议可以达到一样的效果。
更多请参考:Swift中协议的简单介绍