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

协议与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. Retrofit 2.0 超能实践(四),完成大文件断点下载

    作者:码小白 文/CSDN 博客 本文出自:http://blog.csdn.net/sk719887916/article/details/51988507 码小白 通过前几篇系统的介绍和综合运用, ...

  2. Java基本语法-----java运算符

    这块的东西比较多 我写了太慢了 于是在word里写好贴出来供大家一起学习 运算符 -赋值运算符 -比较运算符 -逻辑运算符 -位运算符 -移位操作符 -三元运算符 [正在看本人博客的这位童鞋,我看你气 ...

  3. 2.关于QT中数据库操作,简单数据库连接操作,数据库的增删改查,QSqlTableModel和QTableView,事务操作,关于QItemDelegate 代理

     Linux下的qt安装,命令时:sudoapt-get install qt-sdk 安装mysql数据库,安装方法参考博客:http://blog.csdn.net/tototuzuoquan ...

  4. FFmpeg API 变更记录

    最近一两年内FFmpeg项目发展的速度很快,本来是一件好事.但是随之而来的问题就是其API(接口函数)一直在发生变动.这么一来基于旧一点版本的FFmpeg的程序的代码在最新的类库上可能就跑不通了. 例 ...

  5. 1060. Are They Equal (25)

    题目如下: If a machine can save only 3 significant digits, the float numbers 12300 and 12358.9 are consi ...

  6. (六十八)使用XMPPFramework登录

    按照XMPPFramework的官方样例,应该把登录代码放置在AppDelegate中,并且让注销成为私有方法. XMPPFramework进行登录的步骤如下: ①连接主机,并且发送JID ②如果连接 ...

  7. 《java入门第一季》之网络编程初探

    由于在写有关javaweb的博客,在写到web服务器的时候需要回顾网络编程的知识,提前把网络编程放在前面写. 直接上代码解释: import java.net.InetAddress; import ...

  8. PA模块报错-实际返回的行数超出请求的行数(分析标准FORM报错解决思路)

    录入预算报错时报错: 分析:这个错误是select into 语句返回多行的结果,但具体在哪? 两种方法查找,trace 或者debug 1.trace 启用调试 获取trace文件 -bash-3. ...

  9. C语言的布尔类型(_Bool)

    也许很多人都和我一样,不知道现在的C语言已经有了布尔型:从C99标准开始,类型名字为"_Bool". 在此之前的C语言中,使用整型int来表示真假.在输入时:使用非零值表示真:零值 ...

  10. hadoop队列管理(指定queue跑程序)

    hadoop 升级到cdh5后,队列管理被取消,而是统一用资源池分配. hadoop2.0版本,Hadoop采用了平级队列组织方式,,管理员可将用户分到若干个扁平队列中,在每个队列中,可指定一个或几个 ...