美文网首页
Swift 协议

Swift 协议

作者: 点滴86 | 来源:发表于2016-08-17 16:34 被阅读22次

    协议 属性

    import UIKit
    
    // 协议 属性
    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 如下


    协议 属性.png

    协议 方法

    // 协议 方法
    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 如下


    协议 方法.png

    协议 初始化函数

    // 协议 初始化函数
    protocol SomeProtocol {
        init()
    }
    
    class SomeClass: SomeProtocol {
        required init()
        {
            
        }
    }
    
    class SomeSuperClass {
        init() {
            
        }
    }
    
    class SomeSubClass: SomeSuperClass, SomeProtocol {
        required override init() {
            
        }
    }
    

    协议 作为类型

    // 协议 作为类型
    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 如下


    协议 作为类型.png

    通过扩展添加协议

    // 通过扩展添加协议
    protocol TextRepresentable {
        var textualDescription: String {
            get
        }
    }
    
    extension Dice: TextRepresentable {
        var textualDescription: String {
            return "A \(sides)-sided dice"
        }
    }
    
    print("通过扩展添加协议")
    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 如下


    通过扩展添加协议.png

    扩展遵守 协议

    // 扩展遵守 协议
    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("扩展遵守 协议")
    print(somethingTextRepresentable.textualDescription)
    

    console log 如下


    扩展遵守 协议.png

    协议作为集合类型

    // 协议作为集合类型
    print("协议作为集合类型")
    let things: [TextRepresentable] = [game, d12, simonTheHamster]
    
    for thing in things {
        print(thing.textualDescription)
    }
    

    console log 如下


    协议作为集合类型.png

    协议的继承

    // 协议的继承
    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("协议的继承")
    print(game.prettyTextualDescription)
    

    console log 如下


    协议的继承.png

    协议的组合

    // 协议的组合
    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("协议的组合")
    let birthdayPerson = AnotherPerson(name: "Yao", age: 24)
    wishHappyBirthday(birthdayPerson)
    

    console log 如下


    协议的组合.png

    判断是否遵守协议

    // 判断是否遵守协议
    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("判断是否遵守协议")
    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 如下


    判断是否遵守协议.png

    可选协议

    // 可选协议
    // @objc 声明的协议只能被类遵守,不能被结构体或者枚举遵守
    @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("可选协议")
    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 如下


    可选协议.png

    协议的扩展

    // 协议的扩展
    extension RandomNumberGenerator {
        func randomBool() -> Bool {
            return random() > 0.5
        }
    }
    
    print("协议的扩展")
    let anotherGenerator = LinearCongruentialGenerator()
    print("Here's a random number: \(anotherGenerator.random())")
    print("And here's a random Boolean: \(anotherGenerator.randomBool())")
    

    console log 如下


    协议的扩展.png

    扩展协议提供默认实现

    // 扩展协议提供默认实现
    extension PrettyTextRepresentable {
        var prettyTextualDescription: String {
            return textualDescription
        }
    }
    

    扩展协议添加限制

    // 扩展协议添加限制
    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("扩展协议添加限制")
    print(hamsters.textualDescription)
    

    console log 如下


    扩展协议添加限制.png

    相关文章

      网友评论

          本文标题:Swift 协议

          本文链接:https://www.haomeiwen.com/subject/gubmsttx.html