Swift-11-协议(Protocols)
协议定义了一个蓝图,规定了用来实现某一特定工作或者功能所必须的方法和属性。类、结构体或者枚举类型都可以遵循协议,并提供具体实现来完成协议定义的方法和功能。任意能满足协议要求的类型被称为遵循conform这个协议。
除了遵循协议的类型必须实现那些指定的规定以外,还可以对协议进行扩展,实现一些特殊的规定或者一些附加的功能,使得遵循的类型能够受益。
协议的公式:
protocol SomeProtocol { // 协议内容
}
要使类遵循某个协议,需要在类型名称后加上协议名称,中间以冒号:分隔,作为类型定义的一部分,遵循多个协议时,各协议之间用逗号,分隔。
struct SomeStructure:FirstProtocol,AnotherProtocol{
//结构体内容
}
如果类在遵循协议的同时拥有父类,应该将父类名放在协议名之前,以逗号分隔。
class SomeClass:SomeSuperClass,FirstProtocol,AnotherProtocol{
//类的内容
}
****对属性的规定
协议可以规定其 遵循者提供特定名称和类型的实例属性(instance property)或类属性(type property),而不用指定是存储型属性(stored property)还是计算型属性(calculate property),此外还必须指明是可读的还是可读可写的。
如果协议规定属性是可读可写的,那么这个属性不能是常量或只读的计算属性。如果协议只要求属性是只读的(gettable),那么属性不仅可以是只读的,如果你代码需要的话,也可以是可写的。
协议中的通常用var来声明变量属性,在类型声明后加上{set get}来表示属性是可读可写的,只读属性则用{get}来表示。
protocol SomeProtocol{
var mustBeSettable:Int {get set}//可读可写
var doneNotNeedToBeSettable:Int{get} //只读
}
在协议中定义类属性(type property)时,总是使用static 关键字作为前缀。当协议的遵循者是类时,可以使用class 或static关键字来声明类属性。
protocol AnotherProtocol{
static var someTypeProperty:Int{get set}
}
例子来了····
protocol FullyNamed{
var fullName:String {get}
}
FullyNamed协议除了要求协议的遵循者提供全名属性外,对协议对遵循者的类型并没有特别的要求。这个协议表示,任何遵循FullyNamed协议的类型,都具有一个可读的String类型实例属性fullyName。
//一个遵循FullNamed协议的简单结构体
struct Person:FullyNamed{
var fullName:String
}
let john = Person(fullName:"John Appleseed")
这个例子定义了一个叫做Person的结构体,用来表示具有名字的人,从第一行代码中可以看出,它遵循了FullyNamed协议。
Person结构体的每一个实例都有一个String类型的存储型属性fullName。这正好满足了FullyNamed协议的要求,也就意味着,Person结构体完整地遵循了协议。---如果协议要求未被完全满足,在编译时会报错
class Starship:FullyNamed{
var prefix:String?
var name:String
init(name:String, prefix:String? = nil){
self.name = name
self.prefix = prefix
}
var fullName:String{
return (prefix != nil ? prefix! + "":"")+name
}
}
var ncc = Starship(name:"Enterprise", prefix:"USS")
将fullName属性实现为可读的计算型属性。
******对方法的规定
协议可以要求其遵循者实现某些指定的实例方法或类方法。这些方法作为协议的一部分,像普通的方法一样放在协议的定义中,但是不需要大括号和方法体。可以在协议中定义具有可变参数的方法,和普通的方法定义方式相同。但是在协议的方法定义中,不支持参数默认值。
正如对属性的规定中所说的,在协议中定义类方法的时候,总是使用static关键字作为前缀。当协议的遵循者是类的时候,你可以在类的实现中使用class或者static来定义类方法:
protocol SomeProtocol{
static func someTypeMethod()
}
下面的例子定义了含有一个实例方法的协议:
protocol RandomNumberGenerator{
func random() -> Double
}
******对Mutating方法的规定
有时需要在方法中改变它的示例。eg:值类型(结构体、枚举)的实例方法中,将mutating关键字作为函数的前缀,写在func之前,表示可以在该方法中修改它所属的实例及其实例属性的值。
------用类实现协议中的mutating方法时,不用写mutating关键字;用结构体,枚举实现协议中的mutating方法时,必须写mutating关键字。
*******对构造器的规定
协议可以要求它的遵循者实现特定的构造器,可以在协议的定义里写下构造器的声明,但是不需要写花括号和构造器的实体。
protocol SomeProtocol{
init(someParameter:Int)
}
协议构造器规定在类中的实现
可以在遵循该协议的类中实现构造器,并指定其为类的指定构造器(designated initializer)或者便利构造器(convenience initializer).在这种情况下,你都必须给构造器标上"required"修饰符。
class SomeClass:SomeProtocol{
required init(someParameter:Int){
//构造器的实现
}
}
使用required修饰符可以保证:所有的遵循该协议的子类,同样能为构造器规定提供一个显式的实现或者继承实现。
如果类已经被标记为final,那么不需要在协议构造器的实现中使用required修饰符。因为final类不能有子类。
如果一个子类重写了父类的指定构造器,并且该构造器遵循了某个协议的规定,那么该构造器的实现需要被同事标识required 和override修饰符:
protocol SomeProtocol{
init()
}
class SomeSuperClass{
init(){
//构造器的实现
}
}
class SomeSubClass:SomeSuperClass,SomeProtocol{
//因为遵循协议,需要加上required;因为继承自父类,需要加上override
required override init(){
}
}
****可失败构造器
可以通过给协议Protocols中添加可失败构造器来使遵循该协议的类型必须实现该可失败构造器。
如果在协议中定义一个可失败构造器,则在遵循该协议的类型中必须添加同名同参数的可失败构造器或非可失败构造器。如果在协议中定义一个非可失败构造器,则在遵循该协议的类型中必须添加同名同参数的非可失败构造器或隐式解析类型的可失败构造器(init!).
*****协议类型
尽管协议本身并不实现任何功能,但是协议可以被当做类型来使用。
协议可以像其他普通类型一样使用,使用场景:
1.作为函数、方法或者构造器中的参数类型或者返回值类型;
2、作为常量、变量或者属性的类型;
3.作为数组、字典或者其他容器中的元素类型。
Attention:
协议是一种类型,因此协议类型的名称应与其他类型(Int ,Double,String)的写法相同,使用大写字母开头的驼峰式写法。
Swift-11-协议(Protocols)的更多相关文章
- Swift泛型协议的N种用法
They said "you should learn a new language every year," so I learned Swift. Now I learn ...
- 802.11协议帧格式、Wi-Fi连接交互过程、无线破解入门研究
相关学习资料 Linux黑客大曝光: 第8章 无线网络 无线网络安全攻防实战进阶 无线网络安全 黑客大曝光 第2版 http://zh.wikipedia.org/wiki/IEEE_802.11 h ...
- WIFI:802.11协议帧格式
802协议桢格式 802.11和Wi-Fi技术并不是同一个东西.Wi-Fi标准是802.11标准的一个子集,并且是Wi-Fi联盟负责管理 802协议桢格式: 协议 发布年份/日期 Op.标准频宽 实际 ...
- Welcome-to-Swift-21协议(Protocols)
协议定义了一个方法的蓝图,属性和其他适合特定任务或功能的要求.协议实际上并不提供一个这些要求的实现,它只是描述了一个实现会是什么样子.协议可以通过一个类,结构或枚举提供这些要求的具体实现.满足要求的任 ...
- Swift学习——A Swift Tour 协议和扩展
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/zhenyu5211314/article/details/28854395 Protocols an ...
- 窥探Swift之协议(Protocol)和委托代理(Delegate)回调的使用
协议与委托代理回调在之前的博客中也是经常提到和用到的在<Objective-C中的委托(代理)模式>和<iOS开发之窥探UICollectionViewController(四) - ...
- Swift利用协议优化NSNotificationCenter
NSNotificationCenter存在的问题 通知没有统一的命名格式 对于通知的命名没有强制的要求,一个项目里可能有多种不同的命名规则.比如: 1 2 3 4 5 6 class Barista ...
- swift 当协议遇见了泛型
由于泛型比较简单,并没有单独拿出来介绍!我们在定义函数的时候,有时候只是由于参数或者返回值类型不同,而具体的实现过程是一模一样的,这个时候我们就可以定义泛型函数而使可以传入不同的参数类型: func ...
- 利用Swift之协议语法实现页面间的传值功能
随着Swift 新开发语言的发布,又随着Xcode6.0.1的正式发布,利用swift编写iOS代码迫在眉睫,笔者在使用Objective-C开发近三年以来,对这种优雅的语法深感赞叹,下面我将对比式的 ...
- swift 用协议实现代理传值功能
1.功能简介 RootViewController中用个lable和一个按钮,点击按钮跳转到模态窗口.在模态窗口中有个TextField和一个按钮,输入文字点击关闭模态按钮后跳转到RootViewCo ...
随机推荐
- Zepto源码注释
/* Zepto v1.0-1-ga3cab6c - polyfill zepto detect event ajax form fx - zeptojs.com/license */ ;(funct ...
- Centos下设置静态IP
使用VirtualBox装了很多虚拟机,默认采用的DHCP的方式,但是随着虚拟机越来越多以后,这种方式很不方便,所以需要将机器的IP都设置为静态IP 需要添加的几项内容的解释:IPADDR IP ...
- Odoo ir actions 分析
源代码位置:openerp/addons/base/ir/ir_actions.py 根类型:ir.actions.actions class actions(osv.osv): _name = 'i ...
- C# 取整
double a = 1.1478; Math.Celling(a): 向上取整,结果为2 Math.Float(a); 向下取整,结果为1 Math.Round(a,2); 保留两位小数的奇进偶舍 ...
- 自制Chrome拓展
淘宝试用自动点击: 谷歌其实就是一些html+css+js+静态资源.但是里面有一个特别的配置文件manifest.json.该文件和Android的那个androidmanifest.xml类似,记 ...
- Scrum会议8(Beta版本)
组名:天天向上 组长:王森 组员:张政.张金生.林莉.胡丽娜 代码地址:HTTPS:https://git.coding.net/jx8zjs/llk.git SSH:git@git.coding.n ...
- 插入随机数到MySQL数据库
我们经常会遇到使用随机的问题,下面就是一种解决随机数的方法. 在构造测试数据时,我们需要对测试表插入随机数据.构造测试数据的方法如下,仅以update为例说明 步骤1:随机数的SQL函数为rand() ...
- NBUT 1186 Get the Width(DFS求树的宽度,水题)
[1186] Get the Width 时间限制: 1000 ms 内存限制: 65535 K 问题描述 It's an easy problem. I will give you a binary ...
- 解决mysql出现“the table is full”的问题
解决mysql出现“the table is full”的问题 2010-12-20 09:15:17 分类: LINUX 今天中午收到mysql错误日志监控发来的警报,错误日志如下: 101209 ...
- 设计模式学习系列9 外观模式Facade
1.概述 自己卖了一辆越野自行车,但毕竟不是自己定制的,买回来之后可能需要更改一下脚蹬,座皮,里程计数器或者刹车系统,假如将自行车看做一个整体系统,对我们而言使用的是自行车,然后我们对自己车构件的修改 ...