協(xié)議
協(xié)議為方法鸠项、屬性作媚、以及其他特定的任務需求或功能定義一個大致的框架
。協(xié)議可被類、結(jié)構(gòu)體阐肤、或枚舉類型采納以提供所需功能的具體實現(xiàn)缴罗。滿足了協(xié)議中需求的任意類型都叫做遵循了該協(xié)議况芒。
協(xié)議的定義
- 協(xié)議的定義方式與類肥惭,結(jié)構(gòu)體,枚舉的定義都非常相似
protocol SomeProtocol {
// 屬性
// 方法
}
-
協(xié)議中的屬性
- 不可以有默認值
- 必須設置是
{get}
或者{get set}
喇聊,注意:get與set之間是沒有逗號的 - 必須設置為var
-
協(xié)議中的方法
- 可以定義普通方法也可以是
mutating
方法 - 方法不能有方法體
- 方法的參數(shù)不可以有默認值
- 可以定義普通方法也可以是
protocol Pet {
// 定義屬性
var name: String {get set}
var age: Int {get}
// 定義方法
func feed(food: String)
mutating func shout(sound :String);
}
協(xié)議的遵守格式(實現(xiàn)協(xié)議)
- 格式
class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol {
// 類的內(nèi)容
// 實現(xiàn)協(xié)議中的方法
}
- 實現(xiàn)協(xié)議中的屬性
- 此時屬性可以設置默認值
- 協(xié)議中屬性為可讀可寫的恍风,可以直接聲明為var類型就可以
- 協(xié)議中屬性為可讀屬性,可以直接聲明為let類型就可以誓篱,也可以聲明為var類型
- 實現(xiàn)協(xié)議中的方法
- 可以為方法中的參數(shù)設置默認值
- 在結(jié)構(gòu)體中朋贬,如果需要改變自身的值,需要在方法前面加mutating關鍵字窜骄。在協(xié)議的方法中添加mutating關鍵字锦募,如果結(jié)構(gòu)體來遵守協(xié)議,需要有mutating這個關鍵字邻遏,如果是類來遵守協(xié)議糠亩,mutating關鍵字就不需要了虐骑。
class Cat : Pet{
//屬性可以設置默認值
//可讀可寫用var
var name: String = "Dingding"
//只讀可以用let
let age: Int = 10
func feed(food: String) {
print("feed\(food)")
}
//方法參數(shù)可以有默認值
//類實現(xiàn)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)")
}
//結(jié)構(gòu)體實現(xiàn)mutating方法要修改屬性值時必須加mutating
mutating func shout(sound: String) {
self.name = "Guaiguai"
print("shout\(sound)")
}
}
- 協(xié)議之間的繼承
protocol CrazySportProtocol {
func jumping()
}
//繼承協(xié)議
protocol SportProtocol : CrazySportProtocol {
func playBasketball()
func playFootball()
}
//此時的類必須所有方法都實現(xiàn)
class Person:SportProtocol{
func playBasketball() {
print("playBasketball")
}
func playFootball() {
print("playFootball")
}
func jumping() {
print("jumping")
}
}
協(xié)議中方法的可選
方法一
- 定義協(xié)議
@objc protocol SportProtocol2 {
// 該方法可選
@objc optional func playBasketball()
func playFootball()
}
- 遵守協(xié)議
class Person : SportProtocol2 {
var name : String?
var age : Int = 0
// 實現(xiàn)協(xié)議中的方法,此時可以不實現(xiàn)協(xié)議中的可選方法赎线,當然也可以實現(xiàn)
func playBasketball() {
print("人在打籃球")
}
}
方法二
擴展協(xié)議
protocol SomeProtocol {
func requiredFunc()
func optionalFunc()
}
extension SomeProtocol {
func optionalFunc() {
print("optionalFunc擴展中實現(xiàn)")
}
}
class SomeClass: SomeProtocol {
func requiredFunc() {
print("requiredFunc具體類中實現(xiàn)")
}
}
協(xié)議的運用——代理模式
//1.定義一個協(xié)議廷没,規(guī)定需要完成的任務
protocol BuyTicketProtocol {
func buyTicket()
}
//2.讓具體的類或者結(jié)構(gòu)體實現(xiàn)協(xié)議,將任務具體化
class Assist : BuyTicketProtocol{
func buyTicket() {
print("助手去買票")
}
}
class HN : BuyTicketProtocol{
func buyTicket() {
print("黃牛去買票")
}
}
//3.委托方申明一個屬性(遵循協(xié)議)垂寥,然后在真正需要完成任務的時候調(diào)用屬性來完成
class Person {
// 1.定義協(xié)議屬性
var delegate : BuyTicketProtocol
// 2.自定義構(gòu)造函數(shù)
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()