扩展
扩展可以为一个类型添加新的功能,但是不能重写已有的功能。
使用关键字
extension
来声明扩展。-
计算型属性
扩展可以为已有类型添加计算型实例属性和计算型类型属性。
扩展可以添加新的计算型属性,但是不可以添加存储型属性,也不可以为已有属性添加属性观察器。
-
构造器
扩展能为类添加新的便利构造器,但是不能为类添加新的指定构造器或析构器。指定构造器和析构器必须总是由原始的类实现来提供。
如果你是用扩展提供了一个新的构造器,你依旧有责任确保构造过程能够让实例完全初始化。
-
方法
扩展可以为已有类型添加新的实例方法和类型方法。
-
下标
扩展可以为已有类型添加新下标。
协议
-
属性要求
-
协议总是用
var
关键字来声明变量属性,在类型声明后加上{ set get }
来表示属性是可读可写的,可读属性则用{ get }
来表示。protocol SomeProtocol{ var mustBeSettable: Int { get set} var doesNotNeedToBeSettable: Int { get } }
在协议中定义类型属性时,总是使用
static
关键字作为前缀。
-
-
方法要求
不支持为协议中的方法的参数提供默认值。
-
Mutating方法要求
实现协议中的mutating方法时,若是类类型,则不用写mutating关键字。而对于结构体和枚举,则必须写mutating关键字。
-
构造器要求
在协议的定义里写下构造器的声明,但不需要写花括号和构造器的实体。
构造器要求在类中的实现,必须标上
required
修饰符。使用此修饰符可以确保所有子类也必须提供此构造器实现,从而也能符合协议。如果类已经被标记为
final
,那么不需要在协议构造器的实现中使用required修饰符,因为final类不能有子类。-
如果一个子类重写了父类的指定构造器,并且该构造器满足了某个协议的要求,那么该构造器的实现需要同时标注
required 和 override
修饰符。
-
通过扩展添加协议一致性
通过扩展令已有类型采纳并符合协议时,该类型的所有实例也会随之获得协议中定义的各项功能。
-
通过扩展采纳协议
- 当一个类型已经符合了某个协议中的所有要求,却还没有声明采纳该协议时,可以通过空扩展体的扩展来采纳该协议。
- 即使满足了协议的所有要求,类型也不会自动采纳协议,必须显式的采纳协议。
-
类类型专属协议
可以在协议的继承列表中,通过添加
class
关键字来限制协议只能被类类型采纳,而结构体或枚举不能采纳该协议。class关键字必须第一个出现在协议的继承列表中,在其他继承的协议之前。 -
协议合成
可以罗列任意多个想要采纳的洗衣,并以
与符号(&)
分隔。协议合成并不会生成新的、永久的协议类型,而是将多个协议中的要求合成到一个只在局部作用域有效的临时协议中。
-
检查协议一致性
可以使用类型转换中描述的
is和as
操作符来检查协议一致性,即是否符合某协议,并且可以转换到指定的协议类型。 -
可选的协议要求
可选的协议要求只能用在标记
@objc
特性的协议中。该协议表示协议将暴露给OC代码。即使你不打算和OC有什么交互,如果你想要指定可选的协议要求,那么还是要为协议加上@objc特性。标记@objc特性的协议只能被继承自OC类的类或者@objc类采纳,其他类以及结构体和枚举均不能采纳这种协议。
optional
关键字前也需要添加@objc
import Foundation
@objc protocol CounterDataSource{
@objc optional func incrementForCount(count: Int)
-> Int
@objc optional var fixedIncrement: Int{ get }
}
-
协议扩展
- 通过协议扩展,所有采纳协议的类型,都能自动获得这个扩展所增加的方法实现,无需任何额外修改。
- 通过协议扩展为协议要求提供的默认实现和可选的协议要求不同。如果采纳协议的类型为这些要求提供了自己的实现,那么这些自定义实现将会替代扩展中的默认实现被使用。
-
如果多个协议扩展都为同一个协议要求提供了默认实现,而采纳协议的类型又同时满足这些协议扩展的限制条件,那么将会使用限制条件最多的那个协议扩展提供的默认实现。
泛型
-
类型参数
类型参数指定并命名一个占位类型,并且紧随在函数名后面,使用一对尖括号括起来(例如<T>)。
-
命名类型参数
请始终使用大写字母开头的驼峰命名法,以表明它们是占位类型,而不是一个值。
-
关联类型
通过关键字
associated type
来指定关联类型。