Swift学习笔记十六:协议
Protocol(协议)用于统一方法和属性的名称,而不实现不论什么功能。
协议可以被类。枚举。结构体实现。满足协议要求的类,枚举,结构体被称为协议的遵循者。
遵循者须要提供协议指定的成员,如属性,方法,操作符,下标等。
一、协议的基本的语法
咱们还是先上代码吧
protocol Human {
var name:String{ get set }
var isMan:Bool{set get}
class var isUsable:Bool { set get } //类成员。表示这个类是否可用
func ageDescription(ages:Int...) //函数參数能够是变长參数
}
class Student{
var name = ""
}
class PrimaryStudent:Student,Human{
class var isUsable:Bool{
get{ return self.isUsable }
set{ self.isUsable = newValue }
}
var isMan:Bool
init(name:String,isMan:Bool){
self.isMan = isMan
super.init()
self.name = name
}
func ageDescription(ages:Int...){
var ageCount = 0
for age in ages{
ageCount += age;
}
println("this man age is \(ageCount)")
}
}
重点:
① 遵守某个协议须要像继承一样。在:后面加入这个协议
② 假设既要继承又要遵守协议,须要把继承的父类放在最前面
③ 对于协议中的属性,须要标明属性的读写类型,能够是读写或者仅仅读(不能仅仅写不读)
④ 对于类成员,须要在协议中的属性前面加classkeyword,假设是类遵守协议加classkeyword,假设是枚举或者结构体遵守协议加statickeyword
⑤ 协议中方法支持变长參数,但不支持參数默认值
二、协议类型
虽然协议本身并不实现不论什么功能,可是协议能够被当做类型来使用。
使用场景:
协议类型作为函数、方法或构造器中的參数类型或返回值类型
协议类型作为常量、变量或属性的类型
协议类型作为数组、字典或其它容器中的元素类型
protocol RandomNumberGenerator {
func random() -> Double
}
class Dice {
let sides: Int
let generator: RandomNumberGenerator
init(sides: Int, generator: RandomNumberGenerator) {
self.sides = sides
self.generator = generator
}
func roll() -> Int {
return Int(generator.random() * Double(sides)) + 1
}
}
class LinearCongruentialGenerator: RandomNumberGenerator {
func random() -> Double {
return random()%10.0
}
}
var d6 = Dice(sides: 6,generator: LinearCongruentialGenerator())
解释:
在Dice中。generator是RandomNumberGenerator协议类型。
所以仅仅能使用遵守RandomNumberGenerator协议的类、结构体、枚举类型给他赋值。在后面我们能够看到,在初始化的时候使用遵守RandomNumberGenerator协议的LinearCongruentialGenerator给他赋值了
三、托付代理模式
玩过Objective-C的朋友相比对托付代理非常熟悉了,Swift中的托付代理和OC的大同小异,我们还是来看看代码吧
protocol NameComplete {
func nameSetCompleted(theName:String)
}
class Student{
var delegate:NameComplete?
var name:String{
didSet{
self.delegate?.nameSetCompleted(name)
}
}
init(name:String,delegate:NameComplete){
self.name = name
self.delegate = delegate
}
}
class DoSth:NameComplete{
func nameSetCompleted(theName:String){
println("name:\(theName) is set ")
}
}
var a = DoSth()
var b = Student(name:"",delegate:a)
b.name = "小笨狼" //输出:name:小笨狼 is set
解释:
NameComplete是一个代理。DoSth遵从并实现这个代理,Student调用代理。
在Student中name被赋值之后,代理中nameSetCompleted方法会被调用
三、可选协议
玩过OC的朋友知道。OC中协议有的方法是可选的。在Swift中协议也有这个功能,以下我们来看看
@objc protocol Human{
@optional var name:String{get set}
@optional func descript()
}
class Student:Human{
var name:String = "abc"
func descript(){
println("abc")
}
}
重点:
① 对于可选方法或者属性。须要在方法或者属性前加上@optionalkeyword
② 假设协议中含有可选方法或者属性,在定义协议时须要在protocol 前加上@objckeyword
③ 在可选协议中,不能出现OC没有的类型。比方变长类型
④ 可选协议仅仅能被类遵从
四、协议继承
协议和类一样。也能够继承
protocol pName{
var name:String{set get}
}
protocol dName:pName{
func descript()
}
class Human:dName{
var name = ""
func descript(){
println(name)
}
}
解释:
dName继承了pName,所以dName协议不仅含有一个descript方法还含有name属性,所以遵从dName协议的类必须有name属性和descript方法
五、协议合成
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) //输出Happy birthday Malcolm - you're 21!
解释:
wishHappyBirthday方法传入的參数是<Named, Aged>合成协议类型,这时能够传入遵从这2个协议的结构体的实例
注意:
协议合成并非生成一个新协议。而是多个协议合成一个暂时协议,超出范围后就会失效
Swift学习笔记十六:协议的更多相关文章
- python3.4学习笔记(十六) windows下面安装easy_install和pip教程
python3.4学习笔记(十六) windows下面安装easy_install和pip教程 easy_install和pip都是用来下载安装Python一个公共资源库PyPI的相关资源包的 首先安 ...
- (C/C++学习笔记) 十六. 预处理
十六. 预处理 ● 关键字typeof 作用: 为一个已有的数据类型起一个或多个别名(alias), 从而增加了代码的可读性. typedef known_type_name new_type_nam ...
- Swift学习笔记十
枚举 一个枚举为一组相关联的值定义一个通用类型,并且让你可以在代码中类型安全地操作这些值. C中的枚举将关联的名字指派给一系列整型值.Swift中的枚举类型更为活泼,并不需要为每个成员指定值,如果指定 ...
- Swift 学习笔记十五:扩展
扩展就是向一个已有的类.结构体或枚举类型加入新功能(functionality).扩展和 Objective-C 中的分类(categories)相似.(只是与Objective-C不同的是,Swif ...
- Swift学习笔记十五
自动引用计数(Automatic Reference Counting) 和OC一样,Swift用自动引用计数机制来跟踪和管理你应用程序的内存,大多数情况下,你不需要考虑自己管理内存,Swift会自动 ...
- Swift学习笔记十四
Deinitialization 当类的实例对象即将要被释放时,会立即调用deinitializer,通过deinit关键字来定义deinitializer,和initializer一样,它也只存在于 ...
- Swift学习笔记十二
方法 方法就是和某种特定类型相关联的函数.类.结构体.枚举都可以定义实例方法和类型方法.类型方法和OC中的类方法类似. 结构体和枚举也可以定义方法是Swift与C/OC之间很大的一个区别,在OC中,只 ...
- python3学习笔记十六
1. http协议 GET请求:数据放在url后面 POST请求:数据放在请求体中 <!DOCTYPE html> <html lang="en" ...
- Swift学习笔记十四:构造(Initialization)
类和结构体在实例创建时,必须为全部存储型属性设置合适的初始值. 存储型属性的值不能处于一个未知的状态. 你能够在构造器中为存储型属性赋初值,也能够在定义属性时为其设置默认值.下面章节 ...
随机推荐
- jquery插件--多行文本缩略
1.webkit内核多行缩略样式 text-overflow:ellipsis; display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orie ...
- Linux下安装Oracle 10g(redhat 4)
--注:本篇文章只装Oracle,并没有建库 一:在虚拟机里装个readhat 4系统 二:配IP 配好之后的IP如下: 三:建用户组,用户 注意:oracle用户应具有相同的uid. groupad ...
- C# 导出word文档及批量导出word文档(3)
在初始化WordHelper时,要获取模板的相对路径.获取文档的相对路径多个地方要用到,比如批量导出时要先保存文件到指定路径下,再压缩打包下载,所以专门写了个关于获取文档的相对路径的类. #regio ...
- 【转】C++箴言:理解typename的两个含义
[转载]http://dev.yesky.com/13/2221013.shtml 问题:在下面的 template declarations(模板声明)中 class 和 typename 有什么不 ...
- 分别给出BOOL,int,float,指针变量 与“零值”比较的 if 语句(假设变量名为var)
BOOL型变量:if(!var) int型变量: if(var==0) float型变量: const float EPSINON = 0.00001; if ((x > ...
- 在Mvc中创建WebApi是所遇到的问题
1.提示"The 'ObjectContent`1' type failed to serialize the response body for content type 'applica ...
- php过滤参数特殊字符防注入
分享一例php实现过滤提交的参数数据以防止注入的代码,有需要的朋友参考下. 本节内容: php过滤特符字符,php防注入. in: 后端程序 例子: 代码示例: <?php /** * 安全防范 ...
- 如何给网页标题栏上添加图标(favicon.ico)
favicon.ico详解: favicon是Favorites Icon的缩写,favicon.ico是指显示在浏览器收藏夹.地址栏和标签标题前面的个性化图标. 设置步骤: 1. 把做好的f ...
- SQL Server 2012数据库还原所遇到的问题
在SQL Server2005及以下版本做数据库备份还原时,需要首先建立数据库,然后才能进行数据库还原操作:而在SQL Server2005以上版本做数据库还原时,不需要建立数据库,可以直接进行数据库 ...
- C51的编程规范
现在单片机的程序设计,C51已经得到广泛的推广和应用,算是单片机的主流设计程序,甚至可以说作为单片机开发人员必须要掌握的一门语言了.作为一门工具,最终的目的就是实现功能.在满足这个前提条件下,我们希望 ...