20.Swift学习之协议
协议
协议为方法、属性、以及其他特定的任务需求或功能定义一个大致的框架
。协议可被类、结构体、或枚举类型采纳以提供所需功能的具体实现。满足了协议中需求的任意类型都叫做遵循了该协议。
协议的定义
- 协议的定义方式与类,结构体,枚举的定义都非常相似
protocol SomeProtocol { // 属性 // 方法 }
-
协议中的属性
- 不可以有默认值
- 必须设置是
{get}
或者{get set}
,注意:get与set之间是没有逗号的 - 必须设置为var
-
协议中的方法
- 可以定义普通方法也可以是
mutating
方法 - 方法不能有方法体
- 方法的参数不可以有默认值
- 可以定义普通方法也可以是
protocol Pet { // 定义属性 var name: String {get set} var age: Int {get} // 定义方法 func feed(food: String) mutating func shout(sound :String); }
协议的遵守格式(实现协议)
- 格式
class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol { // 类的内容 // 实现协议中的方法 }
- 实现协议中的属性
- 此时属性可以设置默认值
- 协议中属性为可读可写的,可以直接声明为var类型就可以
- 协议中属性为可读属性,可以直接声明为let类型就可以,也可以声明为var类型
- 实现协议中的方法
- 可以为方法中的参数设置默认值
- 在结构体中,如果需要改变自身的值,需要在方法前面加mutating关键字。在协议的方法中添加mutating关键字,如果结构体来遵守协议,需要有mutating这个关键字,如果是类来遵守协议,mutating关键字就不需要了。
class Cat : Pet{ //属性可以设置默认值 //可读可写用var var name: String = "Dingding" //只读可以用let let age: Int = 10 func feed(food: String) { print("feed\(food)") } //方法参数可以有默认值 //类实现mutating方法要修改属性值时必须加不用加mutating func shout(sound: String = "miaomiao") { self.name = "Caicai" print("shout\(sound)") } } struct Dog : Pet{ var name: String var age: Int func feed(food: String) { print("feed\(food)") } //结构体实现mutating方法要修改属性值时必须加mutating mutating func shout(sound: String) { self.name = "Guaiguai" print("shout\(sound)") } }
- 协议之间的继承
protocol CrazySportProtocol { func jumping() } //继承协议 protocol SportProtocol : CrazySportProtocol { func playBasketball() func playFootball() } //此时的类必须所有方法都实现 class Person:SportProtocol{ func playBasketball() { print("playBasketball") } func playFootball() { print("playFootball") } func jumping() { print("jumping") } }
协议中方法的可选
方法一
- 定义协议
@objc protocol SportProtocol2 { // 该方法可选 @objc optional func playBasketball() func playFootball() }
- 遵守协议
class Person : SportProtocol2 { var name : String? var age : Int = 0 // 实现协议中的方法,此时可以不实现协议中的可选方法,当然也可以实现 func playBasketball() { print("人在打篮球") } }
方法二
扩展协议
protocol SomeProtocol { func requiredFunc() func optionalFunc() } extension SomeProtocol { func optionalFunc() { print("optionalFunc扩展中实现") } } class SomeClass: SomeProtocol { func requiredFunc() { print("requiredFunc具体类中实现") } }
协议的运用——代理模式
//1.定义一个协议,规定需要完成的任务 protocol BuyTicketProtocol { func buyTicket() }
//2.让具体的类或者结构体实现协议,将任务具体化 class Assist : BuyTicketProtocol{ func buyTicket() { print("助手去买票") } } class HN : BuyTicketProtocol{ func buyTicket() { print("黄牛去买票") } }
//3.委托方申明一个属性(遵循协议),然后在真正需要完成任务的时候调用属性来完成 class Person { // 1.定义协议属性 var delegate : BuyTicketProtocol // 2.自定义构造函数 init (delegate : BuyTicketProtocol) { self.delegate = delegate } // 3.行为 func goToBeijing() { print("找代理买票") delegate.buyTicket() print("拿到票去北京") } }
let p = Person(delegate: HN()) p.goToBeijing() let p2 = Person(delegate: Assist()) p2.goToBeijing()
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
开发了5年android,我开始了go学习之旅
做了近5年的android开发,最近项目也是不怎么忙,空闲的时候总会思考一些事情,不过作为移动开发,我个人觉得很有必要学习后台开发,由于公司是Go语言开发的,了解go语言一段时间后,我发现go语言的强大。基于优雅的语法和其强大的并发性,我开启我的go学习之旅。 对Go不太了解的童鞋们可参考:体验golang语言的风骚编程>> golang强大的数据库驱动 Go与PHP不同的地方是Go没有官方提供数据库驱动,而是为开发者开发数据库驱动定义了一些标准接口,开发者可以 根据定义的接口来开发相应的数据库驱动,这样做有一个好处,只要按照标准接口开发的代码, 以后需要迁移数据 库时,不需要任何修改 不乱说用到MySQL还是sqlite3,都需要提前安装数据库驱动 sqlite3 32 位 windows 的安装 1、安装 sqlite3。到http://www.sqlite.org/download.html的页面中,找到 sqlite-dll-win32-x86-3071700.zip 下载解压,并把里面的 dll 文件复制到 windows/system32 目录下。 2、下载 g...
- 下一篇
阿里零售通 App 工程提效实践:提升 50% 的编译速度
前言 当前,大多数 Android 工程都是基于 Gradle 工具进行构建和编译的,一开始,当你的工程不够复杂,或者还只是小型项目的情况下,基本都不需要去关心构建优化的事情,而随着业务变得复杂、代码量的增多以及越来越多的依赖,原有的 单 module 工程变成了多 module 工程,构建时间变得也越来越多。 说到这里,有的同学可能会有疑惑,对于大项目来说,这么多模块和依赖,本来就需要更多的编译时间,还怎么减少构建时间?恰恰相反,实际上越大的项目越能省出来时间。 为了让开发者引起对构建分析的重视,Gradle 官方在最近的版本更新中推出了一个神器 build scan,可视化的深入分析和诊断所有构建相关的数据,并基于此分析结果帮助开发者找出构建问题以及针对构建性能进行优化。 背景 零售通买家端 App 是面向线下小店的一个补货工具,可以快
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Hadoop3单机部署,实现最简伪集群
- CentOS8编译安装MySQL8.0.19
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Mario游戏-低调大师作品
- CentOS6,CentOS7官方镜像安装Oracle11G