协议
协议为方法、属性、以及其他特定的任务需求或功能定义一个大致的框架
。协议可被类、结构体、或枚举类型采纳以提供所需功能的具体实现。满足了协议中需求的任意类型都叫做遵循了该协议。
协议的定义
- 协议的定义方式与类,结构体,枚举的定义都非常相似
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()