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 ...
随机推荐
- ZOJ 3494 (AC自动机+高精度数位DP)
题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3494 题目大意:给定一些被禁止的BCD码.问指定范围内不含有 ...
- python 中chr(),unichr(),ord()的用法
chr()根据整数返回对应的字符,也就是讲ascii转换为字符 unichr()将整数返回成unicode字符 ord()将字符转换成ascii码
- TYVJ P1045 &&洛谷 1388 最大的算式 Label:dp
描述 题目很简单,给出N个数字,不改变它们的相对位置,在中间加入K个乘号和N-K-1个加号,(括号随便加)使最终结果尽量大.因为乘号和加号一共就是N-1个了,所以恰好每两个相邻数字之间都有一个符号.例 ...
- [Unity2D]实现背景的移动
在游戏中通常会实现的效果是玩家主角移动的时候,背景也可以跟着移动,要实现这种效果其实就是获取主角的位置,然后再改变摄像机的位置就可以了,这就需要通过脚本来实现.这个脚本添加到摄像机的GameObjec ...
- HDU 4648 Magic Pen 6
题目链接 6Y什么水平.. #include <cstdio> #include <cstring> #include <string> #include < ...
- [二分图&最小割]
OTL@assassain 反转源汇的模型: 给定一个二分图,同时选择集合中的两个点会有一个代价,选择每一个点有一个收益,问最大收益是多少 (即两个点在不同的集合中是有冲突关系的) 解法: 用最小割模 ...
- C语言根据日期(年,月,日)判断星期几(使用基姆拉尔森计算公式)
C语言根据日期判断星期几(使用基姆拉尔森计算公式) 算法如下: 基姆拉尔森计算公式W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7 在公式中d表示日期中的日数, ...
- 参考XML操作类
转载参考地址: http://blog.csdn.net/happy09li/article/details/7460521
- C++ Split string into vector<string> by space
在C++中,我们有时候需要拆分字符串,比如字符串string str = "dog cat cat dog"想以空格区分拆成四个单词,Java中实在太方便了,直接String[] ...
- MS14-025引起的问题 - 2
5月,微软在13日发布月度安全更新,其中 有KB2871997和 KB2928120两个知识库文章Knowledgeased(而KB2871997甚至不是Security Bulletin).对于无论 ...