协议定义了适合某个特定任务或功能需要的方法、属性和其它需求的一个蓝图。协议本身不提供这些需求的实现,它只是描述了一个任务或功能实现的蓝图。

协议与java 语言中的接口定义类似,都是描述了一个实现可以干什么,而本身却不包含任何实现。与接口不同的是swift语言定义的协议可以被一个类、结构、或者枚举采用,来提供协议规定需求的实际实现,而java 语言的接口只能被类实现。

满足一个协议需求的任何类型(即实现了该协议规定需求)被称为符合该协议。

协议中规定的需求可以是实例属性、实例方法、类型方法、操作符、下标方法等。

1.1 协议语法

协议的定义语法与类、结构和枚举类型类似,以protocol关键字来指示一个协议,并在大括号中规定协议的每一个需求。

protocol SomeProtocol {

// protocol definition goes here

}

一个采用某些协议的特定类型在定义中声明它采用的协议,语法如下:

struct SomeStructure:
FirstProtocol, AnotherProtocol {

// structure definition goes here

}

与接口类似,某个类型可以采用(符合)多个协议。类型采用的每个协议之间用逗号来分割,类型名与协议名之间用冒号分割。

如果一个类有超类,把它的超类名放在它采用的协议名前面,并以一个逗号分割:

class SomeClass: SomeSuperclass,FirstProtocol,AnotherProtocol {

// class definition goes here

}

1.2  协议需求项定义

1) 属性需求

一个协议中的一个属性需求仅对需要属性的属性名和类型进行规定,而不规定这些属性是否是一个存储属性或者是一个计算属性,因此只要一个类型提供一个和该属性需求规定的属性名和类型相同的一个实例属性或者一个类型属性,则该类型就符合该协议规定的这条属性需求。

协议的属性需求也必须规定每个属性是只读的或者是可读写的。

如果一个协议中一个属性需求规定是可读写的,那么该属性需求不能被一个常量存储属性或者一个只读的计算属性满足。如果协议的一个属性需求规定是只读的,那么该属性需求能被任何种类的属性满足。

协议中的属性需求总是作为变量属性被声明(var)。可读写属性通过在类型声明后面添加{ get set }来指示,可读属性用{ get }来指示。协议中的实例属性需求规定如下:

protocol SomeProtocol {

var mustBeSettable:Int {getset }

var doesNotNeedToBeSettable:Int {get }

}

在协议中总是使用class关键字来规定一个类型属性,不管采用该协议的可能是一个结构或枚举,而在该结构或枚举中却是使用static前缀来定义该类型属性,只要该类型属性的其它方面满足协议中对该属性的规定,该属性就是符合协议需求的。

protocol AnotherProtocol {

class var someTypeProperty:Int {getset }

}

2) 方法需求

协议中使用与正常的方法相同的语法来规定一条方法需求,但不允许为方法参数规定默认值。

与属性规定相同,在协议中总是使用class关键字来规定一个类型方法需求,不管采用该协议的一个结构或枚举是使用static前缀来定义该方法,只要该方法的其它方面满足该协议对该方法的规定,其方法就是符合协议需求的。

协议的一条方法需求规定如下所示:

protocol SomeProtocol {

class fund someTypeMethod()

}

3) 变异方法需求

不管采用协议的是一个类,还是一个结构或枚举,协议总是使用mutating关键字来标示一个方法是变异方法。一个采用该协议的类的方法不使用mutating关键字来标示。

如下所示,协议中规定了一条变异方法需求。

protocol Togglable {

mutating functoggle()

}

4)协议中的选项需求

你也能在协议中定义选项需求,这些需求不需要被采用该协议的类型实现(可以实现,也可以不实现)。

选项需求使用@optional关键字来标示。

你可以使用选项链来检查一个选项需求是否被采用该协议的类型实现。

选项属性需求、返回一个值的选项方法需求在它们被存取或调用时总是返回一个适当类型的一个选项。

选项需求仅能够在一个使用@objc 属性进行标记的协议中规定,另外使用@objc 属性进行标记的协议仅能被类所采用,而不能被结构或枚举采用。

如下例子展示了协议中选项需求的定义,以及如何使用选项链来使用协议中规定的选项:

@obj cprotocol CounterDataSource {

@optional func incrementForCount(count:Int)
->Int

@optional var fixedIncrement:Int {get }

}

该协议规定了一条选项方法,一条选项属性。

@objc class Counter {

var count =0

var dataSource:CounterDataSource?

func increment()
{

if let amount =dataSource?.incrementForCount?(count)
{

count +=amount

}else if let amount =dataSource?.fixedIncrement?
{

count +=amount

}

}

}

使用该协议的类Counter也用@objc标记,在该类中使用选项链来读取和调用协议中规定的选项属性和选项方法。

1.3 协议的类型

协议是一种类型。因此可以使用协议作为一个函数、方法或初始化方法中的参数类型或者返回类型;也可以作为一个常量、变量或属性的类型;也可以作为一个数组、词典或其它容器中的项的类型。

由于协议是类型,因此它也能够使用is 和as操作符来检查协议的兼容性,可以使用is 操作符来检查一个实例是否采用了某个协议,使用as操作符来转换一个协议到它的继承链上的另外的协议。

与协议的选项需求规定类似,使用以上操作来检查协议的兼容性也需要协议使用@objc 属性进行标记,另外使用@objc 属性进行标记的协议仅能够被类采用,而不能被结构或枚举采用。

1.4 用扩展来采用协议

能够使用扩展来扩展某个类型(即使已经存在),使该类型采用和符合一个新协议。在扩展中实现新协议规定的方法、属性和下标。

扩展后的类型扩展前的已存在的实例也自动获得协议规定的能力。

语法如下:

extension ExistType:NewProtocol {

// protocol implementation goes here

}

一个已经实现某个协议所有需求的类型如果不明确声明采用该协议,那么它不自动采用那个协议。一个类型采用某个协议,必须被声明。

可以使用一个空的扩展来明确地声明已实现某个协议所有需求的类型采用这个协议。

extension ExistType: NewProtocol {}

1.5 协议的继承

与接口允许继承相同,协议也能够继承。

协议能够继承一个或多个其它的协议,使一个协议在它继承的协议基础上增加进一步的需求。协议继承的语法如下:

protocol InheritingProtocol:SomeProtocol,AnotherProtocol {

// protocol definition goes here

}

1.6  协议的复合

在使用协议作为类型使用时,你能够组合多个协议作为一个临时类型使用,语法为:

protocol<SomeProtocol, AnotherProtocol>,在三角括号内列出要组合的多个协议,每个协议间用逗号分割。

如下例子展示了使用协议组合作为一个函数参数类型的用法。

protocol Named {

var name:String {get }

}

protocol Aged {

var age:Int {get }

}

struct Person:Named,Aged {

var name:String

var age:Int

}

func wishHappyBirthday(celebrator:protocol<Named,Aged>)
{

println("Happy birthday\(celebrator.name) -
you're \(celebrator.age)!")

}

let birthdayPerson =Person(name:"Malcolm",age:21)

wishHappyBirthday(birthdayPerson)

协议复合没有定义一个新的协议,而只是临时组合多个协议作为一个临时协议类型使用。

版权所有,请转载时清楚注明链接和出处,谢谢!

苹果新的编程语言 Swift 语言进阶(十五)--协议的更多相关文章

  1. 苹果新的编程语言 Swift 语言进阶(五)--控制流

    Swift 语言支持C语言全部的控制语句.包含for  和while循环语句,if和switch条件语句,以及break和continue控制语句等. Swift 语言除了支持以上语句,还添加了一个f ...

  2. 苹果新的编程语言 Swift 语言进阶(十四)--扩展

    扩展是为一个已经存在的类.结构.枚举类型添加新功能的一种方式,包括为不能存取源代码的那些已经存在的类型添加功能. 扩展类似于Objective-C语言中的类别,与类别不同的是Swift语言的扩展没有名 ...

  3. 苹果新的编程语言 Swift 语言进阶(十六)--泛型

    泛型允许你定义一个宽松.可重用的函数或者类型,使用泛型能够避免代码的重复,也能以更清楚和抽象的方式来表达程序的意图. 泛型是Swift语言提供的强大功能之一,Swift提供的许多标准库都使用了泛型来创 ...

  4. 苹果新的编程语言 Swift 语言进阶(一)--综述

    Swift 是苹果开发和提供的供开发IOS 和OS X应用的一门新的语言.Swift语言基于C 和Objective-C语言,除了提供C 和Objective-C语言具有的所有语法功能外,为了编程方便 ...

  5. 苹果新的编程语言 Swift 语言进阶(三)--基本运算和扩展运算

    一 基本操作运算 1. 赋值操作 在Swift 中,能够使用赋值操作为一个常量或一个变量赋值,也能够使用多元组一次为多个常量或变量赋值. Swift 的赋值操作与其他语言最大的不同是赋值操作除了可以为 ...

  6. 苹果新的编程语言 Swift 语言进阶(七)--枚举、结构、类

    Swift语言中,具有类特征的类型包括三种,即枚举类型.结构类型(包括基本类型,基本类型实际都是结构类型的特例).类.其中枚举类型.结构类型是属于值类型,类属于引用类型.三种类型都可以添加属性.方法. ...

  7. 苹果新的编程语言 Swift 语言进阶(四)--字符串和收集类型

    一.字符串( String  )和字符类型(Character) 字符串是一种字符的带次序的收集类型(相当于数组),字符是字符串中的元素. 在Swift 语言中,字符串是编码独立的Unicode字符的 ...

  8. 苹果新的编程语言 Swift 语言进阶(二)--基本数据类型

    一  .   常量和变量 Swift语言 对常量和变量的声明进行了明确的区分 Swift语言的常量类型比C 语言的constants类型更加强大,语义更加明确. 常量和变量的区别是常量在设置或初始化后 ...

  9. 苹果新的编程语言 Swift 语言进阶(十)--类的继承

    一.类的继承 类能够从其它类继承方法.属性以及其它特性,当一个类从另外的类继承时,继承的类称为子类,它继承的类称为超类.在Swift中,继承是类区别与其它类型(结构.枚举)的基础行为. 1.1 .类的 ...

随机推荐

  1. volatile足以保证数据同步吗

    上一节已经了解了java内存模型,JMM为了提高执行性能,引入了工作内存和主存两个概念,在继续讨论之前必须先搞清四种存储介质:寄存器.高级缓存.RAM和ROM. RAM与ROM大家都比较熟悉了,可以看 ...

  2. 【一天一道LeetCode】#303.Range Sum Query - Immutable

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 我的个人博客已创建,欢迎大家持续关注! 一天一道le ...

  3. mqtt推送介绍

    方案1.使用GCM服务(Google Cloud Messaging) 简介:Google推出的云消息服务,即第二代的C2DM. 优点:Google提供的服务.原生.简单,无需实现和部署服务端. 缺点 ...

  4. MySQL输入密码后闪退,这里有解

    不知道怎么的,我的MySQL就像抽风了一样,可能是不想理我了吧.只要我输入密码,它就会闪退.而且使用其他的数据库管理工具也是链接不成功的.于是下决心,调教调教它,于是有了下面的这些解决方案. 解决方法 ...

  5. 初探linux子系统集之timer子系统(二)

    想着博客中还没有翻译过一篇文章,虽然英文水平有限,但是借助google翻译慢慢地翻译出一篇文章也是不错的选择.那就来学习下hrtimer的文档吧,翻译的略搓,可以直接跳过这篇,这里仅作为学习的过程!^ ...

  6. Sql Server服务远程过程调用失败

    由于开发系统,需要vs版本统一,于是经过了昨天一整天艰苦卓绝的斗争,小编终于成功的写在了13版本的vs,重新装上了12版本的vs,本来想着,12版本的vs搭建成功了,就赶快搭建框架,然后敲例子,可是天 ...

  7. iOS中 最新支付宝支付(AliPay) 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博 现在的支付方式一般有三种, 支付宝, 微信, 网银. 个人觉得最简单易用的还是支付宝, 微信虽然看起来币支付宝要简单 ...

  8. 手把手教你轻松实现listview上拉加载

    上篇讲了如何简单快速的的实现listview下拉刷新,那么本篇将讲解如何简单快速的实现上拉加载更多.其实,如果你已经理解了下拉刷新的实现过程,那么实现上拉加载更多将变得轻松起来,原理完全一致,甚至实现 ...

  9. mysql DISTINCT 的实现与优化

    DISTINCT实际上和GROUP BY的操作非常相似,只不过是在GROUP BY之后的每组中只取出一条记录而已.所以,DISTINCT的实现和GROUP BY的实现也基本差不多,没有太大的区别.同样 ...

  10. leetcode 生成杨辉三角形, 118 119 Pascal's Triangle 1,2

    Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5, Retu ...