协议声明
一个协议声明为你的程序引入一个命名了的协议类型。协议声明使用 protocol
关键词来进行声明并有下面这样的形式:
protocolprotocol name
:inherited protocols
{
protocol member declarations
}
协议的主体包含零或多个协议成员声明,这些成员描述了任何采用该协议必须满足的一致性要求。特别的,一个协议可以声明必须实现某些属性、方法、初始化程序及下标脚本的一致性类型。协议也可以声明专用种类的类型别名,叫做关联类型,它可以指定协议的不同声明之间的关系。协议成员声明会在下面的详情里进行讨论。
协议类型可以从很多其它协议那继承。当一个协议类型从其它协议那继承的时候,来自其它协议的所有要求就集合了,而且从当前协议继承的任何类型必须符合所有的这些要求。对于如何使用协议继承的例子,查看协议继承
你可以通过采用在类型的扩展声明中的协议来为之前声明的类型添加协议一致性。在扩展中你必须实现所有采用协议的要求。如果该类型已经实现了所有的要求,你可以让这个扩展声明的主题留空。
默认地,符合某一个协议的类型必须实现所有声明在协议中的属性、方法和下标脚本。也就是说,你可以用optional
属性标注这些协议成员声明以指定它们的一致性类型实现是可选的。optional
属性仅仅可以用于使用objc
属性标记过的协议。这样的结果就是仅仅类类型可以采用并符合包含可选成员要求的协议。更多关于如何使用optional
属性的信息及如何访问可选协议成员的指导——比如当你不能肯定是否一致性的类型实现了它们——参见可选协议要求
为了限制协议的采用仅仅针对类类型,需要使用class_protocol
属性标记整个协议声明。任意继承自标记有class_protocol
属性协议的协议都可以智能地仅能被类类型采用。
注意:
如果协议已经用object
属性标记了,class_protocol
属性就隐性地应用于该协议;没有必要再明确地使用class_protocol
属性来标记该协议了。
协议是命名的类型,因此它们可以以另一个命名类型出现在你代码的所有地方,就像协议类型里讨论的那样。然而你不能构造一个协议的实例,因为协议实际上不提供它们指定的要求的实现。
你可以使用协议来声明一个类的代理的方法或者应该实现的结构,就像委托(代理)模式描述的那样。
协议(Protocol)声明语法
协议声明 → 特性(Attributes)列表 可选 protocol 协议名 类型继承子句 可选 协议主体
协议名 → 标识符
协议主体 → { 协议成员声明(Declarations)列表 可选 }
协议成员声明 → 协议属性声明
协议成员声明 → 协议方法声明
协议成员声明 → 协议构造器声明
协议成员声明 → 协议附属脚本声明
协议成员声明 → 协议关联类型声明
协议成员声明(Declarations)列表 → 协议成员声明 协议成员声明(Declarations)列表 可选
协议属性声明
协议声明了一致性类型必须在协议声明的主体里通过引入一个协议属性声明来实现一个属性。协议属性声明有一种特殊的类型声明形式:
var
property name
:type
{ get set }
同其它协议成员声明一样,这些属性声明仅仅针对符合该协议的类型声明了getter
和setter
要求。结果就是你不需要在协议里它被声明的地方实现getter
和setter
。
getter
和setter
要求可以通过一致性类型以各种方式满足。如果属性声明包含get
和set
关键词,一致性类型就可以用可读写(实现了getter
和setter
)的存储型变量属性或计算型属性,但是属性不能以常量属性或只读计算型属性实现。如果属性声明仅仅包含get
关键词的话,它可以作为任意类型的属性被实现。比如说实现了协议的属性要求的一致性类型,参见属性要求
更多参见变量声明
协议属性声明语法
协议属性声明 → 变量声明头(Head) 变量名 类型注解 getter-setter关键字(Keyword)块
协议方法声明
协议声明了一致性类型必须在协议声明的主体里通过引入一个协议方法声明来实现一个方法. 协议方法声明和函数方法声明有着相同的形式,包含如下两条规则:它们不包括函数体,你不能在类的声明内为它们的 参数提供初始值.举例来说,符合的类型执行协议必需的方法。参见必需方法一节。
使用关键字class可以在协议声明中声明一个类或必需的静态方法。执行这些方法的类也用关键字class声明。 相反的,执行这些方法的结构体必须以关键字static声明。如果你想使用扩展方法,在扩展类时使用class关键字, 在扩展结构体时使用static关键字。
更多请参阅函数声明。
协议方法声明语法
协议方法声明 → 函数头 函数名 泛型参数子句 可选 函数签名(Signature)
协议构造器声明
协议声明了一致性类型必须在协议声明的主体里通过引入一个协议构造器声明来实现一个构造器。协议构造器声明 除了不包含构造器体外,和构造器声明有着相同的形式,
更多请参阅构造器声明。
协议构造器声明语法
协议构造器声明 → 构造器头(Head) 泛型参数子句 可选 参数子句
协议下标脚本声明
协议声明了一致性类型必须在协议声明的主体里通过引入一个协议下标脚本声明来实现一个下标脚本。协议属性声明 对下标脚本声明有一个特殊的形式:
subscript (
parameters
) ->return type
{ get set }
下标脚本声明只为和协议一致的类型声明了必需的最小数量的的getter和setter。如果下标脚本申明包含get和set关键字, 一致的类型也必须有一个getter和setter语句。如果下标脚本声明值包含get关键字,一致的类型必须至少包含一个 getter语句,可以选择是否包含setter语句。
更多参阅下标脚本声明。
协议附属脚本声明语法
协议附属脚本声明 → 附属脚本头(Head) 附属脚本结果(Result) getter-setter关键字(Keyword)块
协议相关类型声明
协议声明相关类型使用关键字typealias。相关类型为作为协议声明的一部分的类型提供了一个别名。相关类型和参数 语句中的类型参数很相似,但是它们在声明的协议中包含self关键字。在这些语句中,self指代和协议一致的可能的类型。 获得更多信息和例子,查看相关类型或类型别名声明。
协议关联类型声明语法
协议关联类型声明 → 类型别名头(Head) 类型继承子句 可选 类型别名赋值 可选
易百教程移动端:请扫描本页面底部(右侧)二维码并关注微信公众号,回复:"教程" 选择相关教程阅读或直接访问:http://m.yiibai.com 。
加QQ群啦,易百教程官方技术学习群
注意:建议每个人选自己的技术方向加群,同一个QQ最多限加 3 个群。
- Java技术群: 227270512 (人数:2000,免费:否)
- Go开发者群(新): 851549018 (人数:1000,免费)
- PHP开发者群: 460153241 (人数:2000,免费)
- MySQL/SQL群: 418407075 (人数:2000,免费:否)
- 大数据开发群: 655154550 (人数:2000,免费:否)
- Python技术群: 287904175 (人数:2000,免费:否)
- 人工智能深度学习: 456236082 (人数:2000,免费:否)
- 测试工程师群: 415553199 (人数:2000,免费:否)
- 前端开发者群: 410430016 (人数:2000,免费:否)
- C/C++技术群(新): 629264796 (人数:2000,免费)
- Node.js技术群(新): 621549808 (人数:2000,免费)
- PostgreSQL数据库群: 539504187 (人数:1000,免费)
- Linux运维技术群: 479429477 (人数:2000,免费:否)
- Oracle数据库: 175248146 (人数:2000,免费:否)
- C#/ASP.Net开发者: 579821706 (人数:2000,免费)
- 数据分析师群: 397883996 (人数:2000,免费:否)