Swift.png
協(xié)議的簡單介紹
- 規(guī)定了用來實現(xiàn)某一特定任務(wù)或者功能的方法括堤、屬性砖第,以及其他需要的東西
- 類斟或、結(jié)構(gòu)體 或枚舉都可以遵循協(xié)議素征,并為協(xié)議定義的這些要求提供具體實現(xiàn)(必須要實現(xiàn)協(xié)議的屬性或者方法)
- 協(xié)議的格式:協(xié)議的定義方式與類、結(jié)構(gòu)體和枚舉的定義非常相似
protocol SomeProtocol {
// 這里是協(xié)議的定義部分
}
- 要讓自定義類型遵循某個協(xié)議,在定義類型時御毅,需要在類型名稱后加上協(xié)議名稱根欧,中間以冒號( : )分隔。遵循 多個協(xié)議時端蛆,各協(xié)議之間用逗號( , )分隔
struct SomeStructure: FirstProtocol, AnotherProtocol { // 這里是結(jié)構(gòu)體的定義部分
}
- 擁有父類的類在遵循協(xié)議時咽块,應(yīng)該將父類名放在協(xié)議名之前,以逗號分隔
class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol { // 這里是類的定義部分
}
- 協(xié)議是可以繼承的欺税,一個協(xié)議可以繼承另外一個協(xié)議
屬性的要求
- 協(xié)議可以要求遵循協(xié)議的類型提供特定名稱和類型的實例屬性或類型屬性。
- 協(xié)議不指定屬性是存儲型屬性還是計算型屬性揭璃,它只指定屬性的名稱和類型晚凿。
- 協(xié)議還指定屬性是可讀的還是可讀可寫的。
- 如果協(xié)議要求屬性是可讀可寫的瘦馍,那么該屬性不能是常量屬性或只讀的計算型屬性
- 如果協(xié)議只要求屬性是可讀的歼秽,那么該屬性不僅可以是可讀的,如果代碼需要的話情组,還可以是可寫的燥筷。
- 協(xié)議總是用 var 關(guān)鍵字來聲明變量屬性,在類型聲明后加上 { set get } 來表示屬性是可讀可寫的院崇,可讀屬性則用 { get } 來表示
protocol SomeProtocol {
var mustBeSettable: Int { get set }
var doesNotNeedToBeSettable: Int { get }
}
- 在聲明 類型屬性的時候可以使用 static或者 class關(guān)鍵字
//例子
//定義一個協(xié)議
protocol Work{
var type:String {get set}
var name:String {get set}
}
struct Type:Work{
//類型必須聲明協(xié)議里面的屬性
var type: String;
var name: String;
}
//結(jié)構(gòu)體有逐一構(gòu)造器
let t = Type(type: "互聯(lián)網(wǎng)", name: "IT部門");
t.type
t.name
//打铀撩ァ:"互聯(lián)網(wǎng)" "IT部門"
方法
- 協(xié)議可以要求遵循協(xié)議的類型實現(xiàn)某些指定的實例方法或類方法
- 協(xié)議里面定義的方法不需要大括號和方法體
- 用 static或者class定義類型方法
//定義一個協(xié)議
protocol Run {
func directionRun();
}
//定義一個枚舉
enum Direction:Run {
case left
case right
case up
case down
func directionRun() {
print("跑的方向")
}
}
Direction.left.directionRun();
- 將 mutating 關(guān)鍵 字作為方法的前綴,寫在 func 關(guān)鍵字之前底瓣,表示可以在該方法中修改它所屬的實例以及實例的任意屬性的值(在值類型中谢揪,主要是結(jié)構(gòu)體和枚舉中)
- Mutating 方法:需要在方法中改變方法所屬的實例
- 如果遵循協(xié)議的是 類 則不用寫 mutating 關(guān)鍵字,而對于結(jié)構(gòu)體和枚舉捐凭,則必須寫
mutating 關(guān)鍵字拨扶。
//定義一個協(xié)議
protocol Togglable {
mutating func toggle()
}
//定義一個枚舉 遵循協(xié)議Togglable
enum OnOffSwitch: Togglable {
case Off, On
//更改自身的實例屬性
mutating func toggle() {
switch self {
case .Off:
self = .On
case .On:
self = .Off
}
}
}
var lightSwitch = OnOffSwitch.Off;
lightSwitch.toggle()
// lightSwitch 現(xiàn)在的值為 .On
構(gòu)造器
- 協(xié)議可以要求遵循協(xié)議的類型實現(xiàn)指定的構(gòu)造器
protocol SomeProtocol {
init(someParameter: Int)
}
- 你可以在遵循協(xié)議的類中實現(xiàn)構(gòu)造器,無論是作為指定構(gòu)造器茁肠,還是作為便利構(gòu)造器患民。無論哪種情況,你都必須 為構(gòu)造器實現(xiàn)標(biāo)上 required 修飾符
class SomeClass: SomeProtocol {
required init(someParameter: Int) {
// 這里是構(gòu)造器的實現(xiàn)部分 }
}
如果類已經(jīng)被標(biāo)記為 final 垦梆,那么不需要在協(xié)議構(gòu)造器的實現(xiàn)中使用 required 修飾符匹颤,因為 final 類不能有子類
如果一個子類重寫了父類的指定構(gòu)造器,并且該構(gòu)造器滿足了某個協(xié)議的要求奶赔,那么該構(gòu)造器的實現(xiàn)需要同時標(biāo) 注 required 和 override 修飾符
protocol SomeProtocol {
init()
}
class SomeSuperClass {
init() {
// 這里是構(gòu)造器的實現(xiàn)部分
}
}
class SomeSubClass: SomeSuperClass, SomeProtocol { // 因為遵循協(xié)議惋嚎,需要加上 required
// 因為繼承自父類,需要加上 override
required override init() {
// 這里是構(gòu)造器的實現(xiàn)部分
}
}
代理
- 代理(委托)是一種設(shè)計模式站刑,允許類或結(jié)構(gòu)體將一些需要它們負(fù)責(zé)的功能委托給其他類型的實例
//協(xié)議:遵循class類 方便delege屬性 weak
protocol Work:class {
func test();
}
//工作的員工
class Person:Work {
func test() {
print("開始工作");
}
}
//寵物狗
class Dog: Work {
func test() {
print("旺旺")
}
}
//老板
class Master {
//weak:是修飾 類類型的
weak var delegate:Work?
}
let M = Master();
//設(shè)置代理
M.delegate = Dog();
M.delegate?.test()
讓協(xié)議的方法可選
- 在OC的協(xié)議中方法可以實現(xiàn)也可以不實現(xiàn)另伍,但是在Swift中的協(xié)議中 方法必須要實現(xiàn),解決方法 方swift中的協(xié)議 轉(zhuǎn)化成OC 中協(xié)議
@objc
protocol Work {
//可選擇實現(xiàn) 方法
@objc optional func test();
}
class Person:Work {
}