Swift 協(xié)議

協(xié)議 屬性

import UIKit

// 協(xié)議 屬性
protocol FullyNamed {
    var fullName: String {
        get
    }
}

struct Person: FullyNamed {
    var fullName: String
}

let john = Person(fullName: "John Appleseed")
print("john.fullName is \(john.fullName)")

class Starship: FullyNamed {
    var prefix: String?
    var name: String
    init(name: String, prefix: String? = nil) {
        self.name = name
        self.prefix = prefix
    }
    
    var fullName: String {
        return (prefix != nil ? prefix! + " " : "") + name
    }
}

var ncc1992 = Starship(name: "Enterprise", prefix: "USS")
print("ncc1992.fullName is \(ncc1992.fullName)")

console log 如下


協(xié)議 屬性.png

協(xié)議 方法

// 協(xié)議 方法
protocol RandomNumberGenerator {
    func random() -> Double
}

class LinearCongruentialGenerator: RandomNumberGenerator {
    var lastRandom = 42.0
    let m = 139968.0
    let a = 3877.0
    let c = 29573.0
    func random() -> Double {
        lastRandom = (lastRandom * a + c) % m
        return lastRandom / m
    }
}

let generator = LinearCongruentialGenerator()
print("Here's a random number: \(generator.random())")
print("And another one: \(generator.random())")

protocol Togglable {
    mutating func toogle()
}

enum OnOffSwitch: Togglable {
    case off, on
    mutating func toogle() {
        switch self {
        case .off:
            self = .on
        case .on:
            self = .off
        }
    }
}

var lightSwitch = OnOffSwitch.off
lightSwitch.toogle()

console log 如下


協(xié)議 方法.png

協(xié)議 初始化函數(shù)

// 協(xié)議 初始化函數(shù)
protocol SomeProtocol {
    init()
}

class SomeClass: SomeProtocol {
    required init()
    {
        
    }
}

class SomeSuperClass {
    init() {
        
    }
}

class SomeSubClass: SomeSuperClass, SomeProtocol {
    required override init() {
        
    }
}

協(xié)議 作為類型

// 協(xié)議 作為類型
class Dice {
    let sides: Int
    let generator: RandomNumberGenerator
    init(sides: Int, generator: RandomNumberGenerator) {
        self.sides = sides
        self.generator = generator
    }
    
    func roll() -> Int {
        return Int(generator.random() * Double(sides)) + 1
    }
}

var d6 = Dice(sides: 6, generator: LinearCongruentialGenerator())
for _ in 1...5 {
    print("Random dice roll is \(d6.roll())")
}

protocol DiceGame {
    var dice: Dice {
        get
    }
    
    func play()
}

protocol DiceGameDelegate {
    func gameDidStart(game: DiceGame)
    func game(game: DiceGame, didStartNewTurnWithDiceRoll diceRoll: Int)
    func gameDidEnd(game: DiceGame)
}

class SnakesAndLadders: DiceGame {
    let finalSquare = 25
    let dice = Dice(sides: 6, generator: LinearCongruentialGenerator())
    var square = 0
    var board: [Int]
    init() {
        board = Array(count: finalSquare + 1, repeatedValue: 0)
        board[03] = +08; board[06] = +11; board[09] = +09; board[10] = +02
        board[14] = -10; board[19] = -11; board[22] = -02; board[24] = -08
    }
    
    var delegate: DiceGameDelegate?
    func play() {
        square = 0
        delegate?.gameDidStart(self)
        gameLoop: while square != finalSquare {
            let diceRoll = dice.roll()
            delegate?.game(self, didStartNewTurnWithDiceRoll: diceRoll)
            
            switch square + diceRoll {
            case finalSquare:
                break gameLoop
            case let newSquare where newSquare > finalSquare:
                continue gameLoop
            default:
                square += diceRoll
                square += board[square]
            }
        }
        
        delegate?.gameDidEnd(self)
    }
}

class DiceGameTracker: DiceGameDelegate {
    var numberOfTurns = 0
    func gameDidStart(game: DiceGame) {
        numberOfTurns = 0
        if game is SnakesAndLadders {
            print("Started a new game of Snakes and Ladders")
        }
        
        print("The game is using a \(game.dice.sides)-sided dice")
    }
    
    func game(game: DiceGame, didStartNewTurnWithDiceRoll diceRoll: Int) {
        numberOfTurns += 1
        print("Rolled a \(diceRoll)")
    }
    
    func gameDidEnd(game: DiceGame) {
        print("The game lasted for \(numberOfTurns) turns")
    }
}

let tracker = DiceGameTracker()
let game = SnakesAndLadders()
game.delegate = tracker
game.play()

console log 如下


協(xié)議 作為類型.png

通過擴(kuò)展添加協(xié)議

// 通過擴(kuò)展添加協(xié)議
protocol TextRepresentable {
    var textualDescription: String {
        get
    }
}

extension Dice: TextRepresentable {
    var textualDescription: String {
        return "A \(sides)-sided dice"
    }
}

print("通過擴(kuò)展添加協(xié)議")
let d12 = Dice(sides: 12, generator: LinearCongruentialGenerator())
print(d12.textualDescription)

extension SnakesAndLadders: TextRepresentable {
    var textualDescription: String {
        return "A game of Snakes and Ladders with \(finalSquare) squares"
    }
}

print(game.textualDescription)

console log 如下


通過擴(kuò)展添加協(xié)議.png

擴(kuò)展遵守 協(xié)議

// 擴(kuò)展遵守 協(xié)議
struct Hamster {
    var name: String
    var textualDescription: String {
        return "A hamster named \(name)"
    }
}

extension Hamster: TextRepresentable {
    
}

let simonTheHamster = Hamster(name: "Simon")
let somethingTextRepresentable: TextRepresentable = simonTheHamster
print("擴(kuò)展遵守 協(xié)議")
print(somethingTextRepresentable.textualDescription)

console log 如下


擴(kuò)展遵守 協(xié)議.png

協(xié)議作為集合類型

// 協(xié)議作為集合類型
print("協(xié)議作為集合類型")
let things: [TextRepresentable] = [game, d12, simonTheHamster]

for thing in things {
    print(thing.textualDescription)
}

console log 如下


協(xié)議作為集合類型.png

協(xié)議的繼承

// 協(xié)議的繼承
protocol PrettyTextRepresentable: TextRepresentable {
    var prettyTextualDescription: String {
        get
    }
}

extension SnakesAndLadders: PrettyTextRepresentable {
    var prettyTextualDescription: String {
        var output = textualDescription + ":\n"
        for index in 1...finalSquare {
            switch board[index] {
            case let ladder where ladder > 0:
                output += "▲ "
            case let snake where snake < 0:
                output += "▼ "
            default:
                output += "○ "
            }
        }
        return output
    }
}

print("協(xié)議的繼承")
print(game.prettyTextualDescription)

console log 如下


協(xié)議的繼承.png

協(xié)議的組合

// 協(xié)議的組合
protocol Named {
    var name: String {
        get
    }
}

protocol Aged {
    var age: Int {
        get
    }
}

struct AnotherPerson: Named, Aged {
    var name: String
    var age: Int
}

func wishHappyBirthday(celebrator: protocol<Named, Aged>) {
    print("Happy birthday, \(celebrator.name), you're \(celebrator.age)!")
}

print("協(xié)議的組合")
let birthdayPerson = AnotherPerson(name: "Yao", age: 24)
wishHappyBirthday(birthdayPerson)

console log 如下


協(xié)議的組合.png

判斷是否遵守協(xié)議

// 判斷是否遵守協(xié)議
protocol HasArea {
    var area: Double {
        get
    }
}

class Circle: HasArea {
    let pi = 2.1415927
    var radius: Double
    var area: Double {
        return pi * radius * radius
    }
    init(radius: Double) {
        self.radius = radius
    }
}

class Country: HasArea {
    var area: Double
    init(area: Double) {
        self.area = area
    }
}

class Animal {
    var legs: Int
    init(legs: Int) {
        self.legs = legs
    }
}

let objects: [AnyObject] = [
    Circle(radius: 2.0),
    Country(area: 243_610),
    Animal(legs: 4)
]

print("判斷是否遵守協(xié)議")
for object in objects {
    if let objectWithArea = object as? HasArea {
        print("Area is \(objectWithArea.area)")
    } else {
        print("Something that doesn't have an area")
    }
}

console log 如下


判斷是否遵守協(xié)議.png

可選協(xié)議

// 可選協(xié)議
// @objc 聲明的協(xié)議只能被類遵守,不能被結(jié)構(gòu)體或者枚舉遵守
@objc protocol CounterDataSource {
    @objc optional func increment(count: Int) -> Int
    @objc optional var fixedIncrement: Int {
        get
    }
}

class Counter {
    var count = 0
    var dataSource: CounterDataSource?
    func increment() {
        if let amount = dataSource?.increment?(count) {
            count += amount
        } else if let amount = dataSource?.fixedIncrement {
            count += amount
        }
    }
}

class ThreeSource: NSObject, CounterDataSource {
    let fixedIncrement = 3
}

print("可選協(xié)議")
var counter = Counter()
counter.dataSource = ThreeSource()
for _ in 1...4 {
    counter.increment()
    print(counter.count)
}

@objc class TowardsZeroSource: NSObject, CounterDataSource {
    func increment(count: Int) -> Int {
        if count == 0 {
            return 0
        } else if count < 0 {
            return 1
        } else {
            return -1
        }
    }
}

var anotherCounter = Counter()
anotherCounter.count = -4
anotherCounter.dataSource = TowardsZeroSource()
for _ in 1...5 {
    anotherCounter.increment()
    print(anotherCounter.count)
}

console log 如下


可選協(xié)議.png

協(xié)議的擴(kuò)展

// 協(xié)議的擴(kuò)展
extension RandomNumberGenerator {
    func randomBool() -> Bool {
        return random() > 0.5
    }
}

print("協(xié)議的擴(kuò)展")
let anotherGenerator = LinearCongruentialGenerator()
print("Here's a random number: \(anotherGenerator.random())")
print("And here's a random Boolean: \(anotherGenerator.randomBool())")

console log 如下


協(xié)議的擴(kuò)展.png

擴(kuò)展協(xié)議提供默認(rèn)實(shí)現(xiàn)

// 擴(kuò)展協(xié)議提供默認(rèn)實(shí)現(xiàn)
extension PrettyTextRepresentable {
    var prettyTextualDescription: String {
        return textualDescription
    }
}

擴(kuò)展協(xié)議添加限制

// 擴(kuò)展協(xié)議添加限制
extension CollectionType where Generator.Element: TextRepresentable {
    var textualDescription: String {
        let itemsAsText = self.map{
            $0.textualDescription
        }
        
        return "[" + itemsAsText.joinWithSeparator(",") + "]"
    }
}

let jackTheHamster = Hamster(name: "Jack")
let fiveTwoZeroTheHamster = Hamster(name: "520")
let yaoTheHamster = Hamster(name: "Yao")

let hamsters = [jackTheHamster, fiveTwoZeroTheHamster, yaoTheHamster]

print("擴(kuò)展協(xié)議添加限制")
print(hamsters.textualDescription)

console log 如下


擴(kuò)展協(xié)議添加限制.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市却舀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌肺稀,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,084評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件应民,死亡現(xiàn)場(chǎng)離奇詭異话原,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)诲锹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門繁仁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人归园,你說我怎么就攤上這事黄虱。” “怎么了庸诱?”我有些...
    開封第一講書人閱讀 163,450評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵捻浦,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我桥爽,道長(zhǎng)朱灿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,322評(píng)論 1 293
  • 正文 為了忘掉前任钠四,我火速辦了婚禮盗扒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘缀去。我一直安慰自己侣灶,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評(píng)論 6 390
  • 文/花漫 我一把揭開白布缕碎。 她就那樣靜靜地躺著褥影,像睡著了一般。 火紅的嫁衣襯著肌膚如雪阎曹。 梳的紋絲不亂的頭發(fā)上伪阶,一...
    開封第一講書人閱讀 51,274評(píng)論 1 300
  • 那天,我揣著相機(jī)與錄音处嫌,去河邊找鬼栅贴。 笑死,一個(gè)胖子當(dāng)著我的面吹牛熏迹,可吹牛的內(nèi)容都是我干的檐薯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼注暗,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼坛缕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起捆昏,我...
    開封第一講書人閱讀 38,980評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤赚楚,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后骗卜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宠页,經(jīng)...
    沈念sama閱讀 45,414評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評(píng)論 3 334
  • 正文 我和宋清朗相戀三年寇仓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了举户。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,773評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡遍烦,死狀恐怖俭嘁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情服猪,我是刑警寧澤供填,帶...
    沈念sama閱讀 35,470評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站蔓姚,受9級(jí)特大地震影響捕虽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜坡脐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評(píng)論 3 327
  • 文/蒙蒙 一泄私、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧备闲,春花似錦晌端、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至泻骤,卻和暖如春漆羔,著一層夾襖步出監(jiān)牢的瞬間梧奢,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工演痒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留亲轨,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,865評(píng)論 2 370
  • 正文 我出身青樓鸟顺,卻偏偏與公主長(zhǎng)得像惦蚊,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子讯嫂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評(píng)論 2 354

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

  • 轉(zhuǎn)載:http://www.reibang.com/p/e70bd6645d88前言 熟悉Objective-C語...
    guoshengboy閱讀 1,041評(píng)論 0 1
  • 協(xié)議語法 實(shí)現(xiàn)協(xié)議 擁有父類的類在采納協(xié)議時(shí)蹦锋,應(yīng)該將父類名放在協(xié)議名之前,以逗號(hào)分隔: 協(xié)議的屬性要求 協(xié)議不指定...
    666真666閱讀 1,696評(píng)論 0 2
  • 協(xié)議 協(xié)議是一種表示類型的相通性的方法欧芽,往往這些類型某些方面迥異莉掂。比如,一個(gè)Bee對(duì)象和一個(gè)Bird對(duì)象就在飛行方...
    小松樹先生閱讀 1,016評(píng)論 0 0
  • 定義:協(xié)議為方法千扔、屬性巫湘、以及其他特定的任務(wù)需求或功能定義藍(lán)圖。 協(xié)議可被類昏鹃、結(jié)構(gòu)體尚氛、或枚舉類型采納以提供所需功能的...
    json_jie閱讀 337評(píng)論 0 0
  • 協(xié)議的語法 屬性要求 // 協(xié)議可以要求所有遵循該協(xié)議的類型提供特定名字和類型的實(shí)例屬性或類型屬性。協(xié)議并不會(huì)具體...
    風(fēng)___________閱讀 284評(píng)論 0 0