Swift--協(xié)議--10

----協(xié)議的定義----

//協(xié)議:方法萤捆,屬性或一段功能的藍本
//協(xié)議可被類恩伺,結(jié)構(gòu)體和枚舉“領(lǐng)養(yǎng)”從而“長大成人”
//任何滿足協(xié)議的“需求”的類型堤器,被稱為“遵從”該協(xié)議

protocol APro {
    
}

protocol BPro {
    
}
//領(lǐng)養(yǎng)/遵從若干個協(xié)議川蒙,用逗號分隔
struct AStruct : APro,BPro {
    
}

//超類在協(xié)議之前
class Name {
    
}

class GiveName:Name,APro,BPro {
    
}

----屬性協(xié)議----

屬性協(xié)議:顧名思義庙睡,要求遵從實現(xiàn)已制定的名稱實現(xiàn)屬性,但具體實現(xiàn)是實例屬性或類型屬性并不關(guān)心

//可以指定要求實現(xiàn)getter和setter+getter揪漩,屬性必須定義為變量 var

protocol FileAccessPriority {
    var readOnly : Bool { get }
    var readWrite : Bool { get set}
}

protocol AccessUrl {
    static var link:String {get}
}

//遵從實例屬性協(xié)議   例子1
protocol FullName {
    var fName : String {get}
    var gNAme : String {get}
}

struct Student : FullName {
    var gNAme: String
    var fName: String
}

var stu1 = Student(gNAme: "老王", fName: "隔壁")
stu1.fName
stu1.gNAme



//遵從實例屬性協(xié)議 例子2
class SomeBody : FullName {
    var title: String?
    var name: String
    
    init(title:String? ,name:String) {
        self.title = title
        self.name = name
    }
    
    var gNAme: String {
        return name
    }
    
    var fName: String {
        return title ?? "無名小將"
    }
    
    var desc : String {
        return self.fName + self.gNAme
    }
}

var somebody1 = SomeBody(title: "大帝", name: "亞歷山大")
somebody1.gNAme
somebody1.fName
somebody1.desc


var noBody = SomeBody(title: nil, name: "小波")
noBody.fName
noBody.gNAme
noBody.desc

----屬性協(xié)議----

方法協(xié)議:定義使沒有{}執(zhí)行體,實現(xiàn)僅要求名稱相同
作用:可以讓一個類/結(jié)構(gòu)體/枚舉的方法吏口,分解為更小的組合奄容,從而更加靈活性

//類型方法協(xié)議:前綴總是static
protocol AMethod {
    static func foo()
}


class A :AMethod {
    class func foo() {
        print("哈哈哈")
    }
}


A.foo()

//實例方法協(xié)議
protocol RandomGeneratable {
    func randomNumber() -> Int
}

struct RandomNumber :RandomGeneratable {
    func randomNumber() -> Int {
        return Int(arc4random())
    }
}


struct RandomNumberInsix : RandomGeneratable {
    func randomNumber() -> Int {
        return Int(arc4random()) % 6
    }
}


let random1 = RandomNumber()
random1.randomNumber()


let random2 = RandomNumberInsix()
random2.randomNumber()
//結(jié)構(gòu)體冰更,枚舉的 “變異方法協(xié)議”
protocol Switchable {
   mutating func onOff()
}

enum MySwitch : Switchable {
   mutating func onOff() {
        switch self {
        case .off:
        self = .on
        default:
            self = .off
        }
    }
    case on,off
}

----構(gòu)造方法協(xié)議----

構(gòu)造方法協(xié)議:可以要求遵從者實現(xiàn)指定的構(gòu)造方法
實現(xiàn)時用required init,編譯器會提示添加昂勒,無需手動添加required

protocol AA {
    init(a:Int)
}

struct B : AA {
    init(a : Int) {
        
    }
}

class C : AA {
    required init(a: Int) {
        
    }
}
//協(xié)議作為類型使用: 可用于參數(shù)類型/返回類型蜀细; 變量/常量/屬性 ;集合類型中的元素類型

//實例方法協(xié)議
protocol RandomGeneratable {
    func randomNumber() -> Int
}

struct RandomNumber :RandomGeneratable {
    func randomNumber() -> Int {
        return Int(arc4random())
    }
}

class TenRandomNumber  : RandomGeneratable{
    func randomNumber() -> Int {
        return Int(arc4random()) % 10 + 1
    }
}


struct Dice {
    var sides : Int
    var randomNumber : RandomGeneratable
    
    func play() -> Int {
        return self.randomNumber.randomNumber() % sides + 1
    }
}

let aDice = Dice(sides: 6, randomNumber: RandomNumber())

----協(xié)議作為代理----

協(xié)議作為代理:代理是一種常見的設(shè)計模式戈盈,可以讓類或結(jié)構(gòu)體把一部分職責奠衔,指派給非同類的實例去承擔

/*
 1.若要尋求代理,可以通過定義一個協(xié)議塘娶,打包要實現(xiàn)的職責于其中
 2.該代理協(xié)議的遵從者就可以實現(xiàn)這些打包的職責
 3.代理在IOS開發(fā)中归斤,一般可以用于響應(yīng)特定的操作,或從外部數(shù)據(jù)源取回數(shù)據(jù)但無需了解是何種數(shù)據(jù)源
 */

struct Role {
    var name : String
}

protocol Player {
    var role : Role {get}
    mutating func play()
}

protocol GameDelegate {
    func start(with player: Player) -> Int
    func rolePK(with player: Player,armed:Bool) -> Int
    func end(with player: Player) -> Int
}

struct GameAgent : GameDelegate {
    func start(with player: Player) -> Int {
        print(player.role.name,"開啟游戲刁岸,獲得經(jīng)驗脏里,2000")
        return 2000
    }
    
    func rolePK(with player: Player, armed: Bool) -> Int {
        if armed {
            print(player.role.name, "PK 開始,有武器虹曙,獲得5000經(jīng)驗")
            return 5000
        } else {
            print(player.role.name, "PK 開始迫横,沒有武器,獲得2500經(jīng)驗")
            return 2500
        }
    }
    
    func end(with player: Player) -> Int {
        print(player.role.name, "正常退出酝碳,獲得1000經(jīng)驗")
        return 1000
    }
}


struct MirPlayer : Player {
    var exp : Int
    var gameAgent : GameAgent?
    
    var role: Role
    
    mutating func play() {
        if let gameAgent = gameAgent {
            print("您使用了代練")
            
            exp += gameAgent.start(with: self)
            exp += gameAgent.rolePK(with: self, armed: true)
            exp += gameAgent.end(with: self)
            
        } else {
            print("您還沒有開始代練矾踱,不能自動升級")
        }
    }
    
    
}


let role = Role(name: "小波")
var play1 = MirPlayer(exp: 0, gameAgent: nil, role: role)
play1.play()


let role2 = Role(name: "土豪玩家")
let agent = GameAgent()
var play2 = MirPlayer(exp: 0, gameAgent: agent, role: role2)
play2.play()

----協(xié)議擴展和約束-----

//協(xié)議擴展:即使無源碼權(quán)限下,給已有的類添加協(xié)議
//即存實例會自動遵從添加了的協(xié)議

let  a = 1
protocol ShowHint {
    func hint() -> String
}


extension Int : ShowHint {
    func hint() -> String {
        return "整數(shù):\(self)"
    }
}

a.hint()
(-2123).hint()


//如果一個類型預(yù)遵從了協(xié)議疏哗,可以直接拓展協(xié)議
struct Lesson {
    var name : String
    var description : String {
        return "課程名是: " + name
    }
}

1.description
extension Lesson : CustomStringConvertible {}


//擴展約束:可以在擴展協(xié)議的同時呛讲,加上限定條件,where語句
extension ShowHint where Self:CustomStringConvertible {
    func hint2() -> String {
        return "我是一個能顯示成字符串的類型" + self.description
    }
}

1.hint2()





//集合類型 Collection  也是一種協(xié)議沃斤,Iterator.Element指代其中的元素
let array = [1,2,3,4]
print(array)

extension Collection where Iterator.Element : CustomStringConvertible {
    func newDesc() -> String {
        let itemAsText = self.map { $0.description}
        return "該集合類型元素數(shù)目是\(self.count),元素的值是" + itemAsText.joined(separator: ",")
        
    }
}

array.newDesc()
print(array)

----協(xié)議的集合類型-----

//協(xié)議的集合類型:因為協(xié)議可以作為類型使用圣蝎,可把遵從相同協(xié)議的實例放到一個協(xié)議類型的數(shù)組
let array1 : [CustomStringConvertible] = [1,2,3,"haha"] //as [Any]

for i in array1 {
    print(i)
}

----協(xié)議繼承和默認實現(xiàn)-----

協(xié)議繼承:一個協(xié)議可以繼承若干個協(xié)議,并可以在繼承基礎(chǔ)上添加新需求衡瓶,與class繼承類似徘公,區(qū)別是class不能多重繼承,對結(jié)構(gòu)體進行協(xié)議擴展哮针,相當于實現(xiàn)了多重繼承(面向協(xié)議編程)

//繼承的多個協(xié)議間用逗號分隔
protocol MyPrintable : CustomStringConvertible,CustomPlaygroundQuickLookable {
    
}

struct MyContent {
    var text : String
    var mycustomtext : String
}


//提供默認實現(xiàn):可以給協(xié)議擴展提供一個默認的實現(xiàn)关面,任何遵從此協(xié)議的類型都會獲得
extension MyPrintable {
    var customPlaygroundQuickLook: PlaygroundQuickLook {
        return PlaygroundQuickLook.text("Playground的默認預(yù)覽文字")
    }
}


extension MyContent : MyPrintable {
    var description: String {
        return self.text
    }
    
//    var customPlaygroundQuickLook: PlaygroundQuickLook {
//        return PlaygroundQuickLook.text(self.mycustomtext)
//    }
}


let mycontent1 = MyContent(text: "內(nèi)容", mycustomtext: "保留文字")
mycontent1.description

----類專用協(xié)議-----

類專用協(xié)議:可以把協(xié)議限制在class類型(讓結(jié)構(gòu)體和枚舉無法使用),加關(guān)鍵字class到協(xié)議繼承列表的第一位

protocol OnlyforClass : class {
    
}

class MyText : OnlyforClass {
    var desc : String {
        return "a"
    }
}

/*
struct MyStruct : OnlyforClass {
    //報錯
}
*/

----協(xié)議組合-----

協(xié)議組合:多個協(xié)議臨時組合在一起的類型十厢,形式:協(xié)議1 & 協(xié)議2 &...>

protocol Ageable {
    var age : Int {get}
}

protocol Nameable {
    var name : String {get}
}

struct Student : Ageable,Nameable {
    var age: Int
    var name: String
}

struct Teacher : Ageable,Nameable {
    var age: Int
    var name: String
    var title : String
}

func wish(someone: Ageable & Nameable) {
    print("祝",someone.name,someone.age,"歲生日快樂5忍!蛮放!")
}

let student1 = Student(age: 10, name: "Tom")
let teacher1 = Teacher(age: 40, name: "Bob", title: "professor")

wish(someone: student1)
wish(someone: teacher1)

----協(xié)議檢查和轉(zhuǎn)換-----

協(xié)議檢查和轉(zhuǎn)換:使用is和as類型轉(zhuǎn)換操作符來檢查協(xié)議遵守與否,或轉(zhuǎn)換成特定的協(xié)議

protocol Slogan {
    var desc : String {get}
}

protocol Coder : Slogan {
    var name : String {get}
}

struct JavaCoder : Coder {
    var name: String
    var desc: String {
        return "我會java缩抡,我很牛"
    }
}

struct JSCoder : Coder {
    var name: String
    var desc: String {
        return "我會js,我很潮"
    }
}


struct Newbie {
    var name : String
    
}


let java1 = JavaCoder(name: "小慕")
let js1 = JSCoder (name: "小課")
let newbie1 = Newbie(name: "小波")


let coders = [java1,js1,newbie1] as [Any]


for coder in coders {
    if let coder = coder as? Coder {
        print(coder.name,coder.desc)
    } else {
        print("你不是一個程序員")
    }
    
    
    if let newbie = coder as? Newbie {
        print(newbie.name,"你是一個菜鳥")
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末包颁,一起剝皮案震驚了整個濱河市瞻想,隨后出現(xiàn)的幾起案子压真,更是在濱河造成了極大的恐慌,老刑警劉巖蘑险,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件滴肿,死亡現(xiàn)場離奇詭異,居然都是意外死亡佃迄,警方通過查閱死者的電腦和手機泼差,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來呵俏,“玉大人堆缘,你說我怎么就攤上這事〔裥牛” “怎么了套啤?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長随常。 經(jīng)常有香客問我潜沦,道長,這世上最難降的妖魔是什么绪氛? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任唆鸡,我火速辦了婚禮,結(jié)果婚禮上枣察,老公的妹妹穿的比我還像新娘争占。我一直安慰自己,他們只是感情好序目,可當我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布臂痕。 她就那樣靜靜地躺著,像睡著了一般猿涨。 火紅的嫁衣襯著肌膚如雪握童。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天叛赚,我揣著相機與錄音澡绩,去河邊找鬼。 笑死俺附,一個胖子當著我的面吹牛肥卡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播事镣,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼步鉴,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起唠叛,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤只嚣,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后艺沼,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡蕴掏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年障般,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盛杰。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡挽荡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出即供,到底是詐尸還是另有隱情定拟,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布逗嫡,位于F島的核電站青自,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏驱证。R本人自食惡果不足惜延窜,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望抹锄。 院中可真熱鬧逆瑞,春花似錦、人聲如沸伙单。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吻育。三九已至念秧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間扫沼,已是汗流浹背出爹。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留缎除,地道東北人严就。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像器罐,于是被迫代替她去往敵國和親梢为。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 132.轉(zhuǎn)換錯誤成可選值 通過轉(zhuǎn)換錯誤成一個可選值,你可以使用 try? 來處理錯誤。當執(zhí)行try?表達式時,如果...
    無灃閱讀 1,251評論 0 3
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理铸董,服務(wù)發(fā)現(xiàn)祟印,斷路器,智...
    卡卡羅2017閱讀 134,656評論 18 139
  • 本章將會介紹 協(xié)議語法屬性要求方法要求(Method Requirements)Mutating 方法要求構(gòu)造器要...
    寒橋閱讀 419評論 0 3
  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 3,805評論 1 10
  • 人粟害,累了就該休息蕴忆,休息夠了,那就要繼續(xù)奮斗悲幅。兩天前我還是那個心里發(fā)慌套鹅、遇事打怵的狀態(tài),可是汰具,今天下午就調(diào)整狀態(tài)...
    木子xinyu閱讀 315評論 0 0