第二十一章 协议
协议定义了一个蓝图,规定了用来实现某一特定任务或者功能的方法,属性,以及其他需要的东西。类,结构体或枚举都可以遵循协议,并为协议定义的这些要求提供具体实现。某个类型能够满足某个协议的要求,就可以说该类型遵循这个协议。
除了遵循协议的类型必须实现的要求外,还可以对协议进行扩展,通过扩展来实现一部分要求或者实现一些附加功能,这样遵循协议的类型就能够使用这些功能。
1. Protocol Syntax (协议语法)
我们可以像定义类,结构体和枚举那样定义一个协议。
// 协议名首字母要大写
protocol SomeProtocol {
// protocol definition goes here
}
某个自定义的类型如结构体,类或者枚举都可以采用一个或多个协议,可以在结构体名称的后面添加上一个自定义的协议,用此来作为该结构体的一部分,如果该结构体采用了多个协议,可以用,
来分开这些协议。
struct SomeStructure: FirstProtocol, AnotherProtocol {
// structure definition goes here
}
某个类用一个父类的情况下,可以在该类的名称后面引用其父类,
class SomeClass: SomeSuperclass, FirstProtocol, AnotherProtocol {
// class definition goes here
}
2. Property Requirements (属性要求)
一个协议可以要求任何确认的类型以特定的名字或类型来提供一个实例属性或类型属性。这个协议不必指明说这个属性是存储还是计算型属性,仅仅只是指明了该需求的属性名和类型,还指明了这个属性是可读还是可写的。(gettable
,settable
)
如果说这个协议要求属性必须是可读或可写的,那么这个属性要求就不能通过一个常量存储属性或只读的计算属性而得到满足和实现。如果说该协议值是要求属性是可写的那么可以通过任何类型的属性来满足这个协议的要求。如果代码需要的话该属性同样也可以是可写的。
属性要求总是要以变量属性声明定义的并且要加上前缀var
关键字,可读和可写的属性都要在类型的定义里面通过写{get set}
来指明该属性是可读和可写的属性。
protocol SomeProtocol {
// 可读和可写的属性
var mustBeSettable: Int {
get set }
// 可写属性
var doesNotNeedToBeSettable: Int {
get }
}
如果想要在协议里面添加类型属性要求的时候必须要用static
关键字,如果说这个类型属性要求要在类的实现里面的,同样的要用static
或class
关键字。
protocol AnotherProtocol {
static var someTypeProperty: Int {
get set }
}
// 单个实例属