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 ...
随机推荐
- Origami
Origami 是一个来自 Facebook 设计团队的作品,是 Quartz Composer 的免费工具包,可在无需编程的情况下轻松实现与设计原型进行交互.
- xubuntu12.04配置
更改源:我用上海交通大学的 首先备份Ubuntu12.04源列表sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup #(备份下当前 ...
- HDU 2852 KiKi's K-Number(离线+树状数组)
题目链接 省赛训练赛上一题,貌似不难啊.当初,没做出.离线+树状数组+二分. #include <cstdio> #include <cstring> #include < ...
- pygame系列_百度随心听_完美的UI设计
这个程序的灵感来自于百度随心听 下面是我的程序截图: 说明: 动作按钮全部是画出来的,没有用到任何图片 用到图片的只有:背景,歌手图片,作者图片 代码正在调试中.... 如果你鼠标移动到黄色小圆里面, ...
- c++ namespace的使用
** namespace:命名空间就是为解决C++中的变量.函数的命名冲突而服务的. ** namespace定义的格式基本格式是: namespace identifier { entitie ...
- ASP.NET后台JS弹框使前台页面样式丢失 解决办法
Response.Write("<script>alert('您还没有上传相关图片!');</script>");是向前台输出js 应该用下面的方法 Cli ...
- 1.Java为什么能跨平台运行?请简述原理。
使用不同操作系统的JVM(JAVA虚拟机)解释运行编译好的字节码文件(.class)
- fibonacci数列 java
public class Fibonacci { public static void main(String agrs[]) { ;j<=;j++) System.out.println(fo ...
- CSS3动画(动画已丢,看原文)
原文:http://ued.1905.com:8880/sample/css3/base/test.html CSS3动画 简要展示了CSS3常用动画效果,以及所使用代码. bounce 复制 展开代 ...
- Excel中如何在两个工作表中查找重复数据
有时我们可能会在两种工作表中查找重复记录,当数据记录很多时,就必须通过简单的方法来实现.下面小编就与大家一起分享一下查看重复记录数据的方法,希望对大家有所帮助. 方法/步骤 为了讲解的需要,小编特 ...