iOS --- 面向协议的编程(swift2.3)

来源:互联网 发布:雷欧mac全灭图解 编辑:程序博客网 时间:2024/05/21 22:56

iOS — 面向协议的编程(swift)

下面简单的介绍面向协议的编程的应用

  1. 扩展协议和默认实现

  2. 面向协议编程

  3. 协议聚合

  4. 泛型约束

  5. swift是面向协议的编程语言

  6. UIKit中的委托模式

  7. 创建自己的委托模式

  8. 可选的协议方法


一:扩展协议和默认实现

protocol Record: CustomStringConvertible{    var wins: Int {get}    var losses: Int {get}    func winningPercent() -> Double}// 扩展一个协议的时候,可以拥有实现!,那么就是说,虽然协议不能够实现属性和方法,但是在协议的扩展里面可以实现属性和方法extension Record{    //那么遵守CustomStringConvertible协议必须实现的属性就可以写在协议的扩展里面,那么结构体和类中就可以不写,打印出来的结果就是自定义的格式    //这个例子就是告诉我们,在协议的扩展中,可以实现属性和函数的逻辑,在类和结构中就不需要实现了    var description: String{        return String(format: "WINS: %d , LOSSES: %d", arguments: [wins,losses])    }    func shoutWins(){        print("WE WIN",wins,"TIMES!!!")    }    var gamePlayed: Int{        return wins + losses    }}struct BasketballRecord: Record{    var wins: Int    var losses: Int    func winningPercent() -> Double {        //return Double(wins)/Double(wins + losses)        return Double(wins)/Double(gamePlayed)    }}//extension BasketballRecord: CustomStringConvertible{}struct BaseballRecord: Record{    var wins: Int    var losses: Int    func winningPercent() -> Double {        return Double(wins)/Double(gamePlayed)    }}let teamRecord = BasketballRecord(wins: 2, losses: 10)print(teamRecord)teamRecord.shoutWins()// 扩展标准库中的协议extension CustomStringConvertible{    var descriptionWithDate: String{        return NSDate().description + " " + description    }}print( teamRecord.descriptionWithDate )

二:面向协议编程

protocol Record: CustomStringConvertible{    var wins: Int {get}    var losses: Int {get}    //func winningPercent() -> Double}extension Record{    var description: String{        return String(format: "WINS: %d , LOSSES: %d", arguments: [wins,losses])    }    var gamePlayed: Int{        return wins + losses    }}protocol Tieable{    var ties: Int{get set}}//由于有些比赛没有平局,那么我只想给有平局的结构和类增加一个协议的扩张,用where关键字,表示如果这个类或者结构遵守了Tieable协议的话,我就给他扩展这个平局的属性,然后再将gamePlayed和winningPercent的实施细则重写,覆盖在协议中默认的内容,那么如果,我们类或结构遵守了Tieable这个协议的话,我们就可以直接使用这个被覆盖的gamePlayed属性和winningPercent方法了extension Record where Self: Tieable{    var gamePlayed: Int{        return wins + losses + ties    }    func winningPercent() -> Double {        return Double(wins)/Double(wins + losses + ties)    }}struct BasketballRecord: Record{    var wins: Int    var losses: Int//    func winningPercent() -> Double {//        return Double(wins)/Double(gamePlayed)//    }}//由于在Record协议里面有一个默认的gamePlayed属性实现过程,但是在我们的具体的结构和类中,可以重写这个属性的实现,也就是可以覆盖协议扩展中属性的实现过程struct BaseballRecord: Record{    var wins: Int    var losses: Int    let gamePlayed = 162//    func winningPercent() -> Double {//        return Double(wins)/Double(gamePlayed)//    }}struct FootballRecord: Record, Tieable{    var wins: Int    var losses: Int    var ties: Int//    var gamePlayed: Int{//        return wins + losses + ties//    }////    func winningPercent() -> Double {//        return Double(wins)/Double(wins+losses+ties)//    }}let basketballTeamRecord = BasketballRecord(wins: 2, losses: 10)let baseballTeamRecord = BaseballRecord(wins: 10, losses: 5)basketballTeamRecord.gamePlayedbaseballTeamRecord.gamePlayedlet footballTeamRecord = FootballRecord(wins: 1, losses: 1, ties: 1)footballTeamRecord.gamePlayedfootballTeamRecord.winningPercent()

三:协议聚合

protocol Record: CustomStringConvertible{    var wins: Int {get}    var losses: Int {get}}extension Record{    var description: String{        return String(format: "WINS: %d , LOSSES: %d", arguments: [wins,losses])    }    var gamePlayed: Int{        return wins + losses    }    func winningPercent() -> Double {        return Double(wins)/Double(gamePlayed)    }}protocol Tieable {    var ties: Int {get set}}extension Record where Self: Tieable{    var gamePlayed: Int{        return wins + losses + ties    }    func winningPercent() -> Double {        return Double(wins)/Double(wins + losses + ties)    }}protocol Prizable{    func isPrizable() -> Bool}struct BasketballRecord: Record, Prizable{    var wins: Int    var losses: Int    func isPrizable() -> Bool{        return wins > 2    }}struct BaseballRecord: Record, Prizable{    var wins: Int    var losses: Int    let gamePlayed = 162    func isPrizable() -> Bool{        return gamePlayed > 10 && winningPercent() >= 0.5    }}struct FootballRecord: Record, Tieable, Prizable{    var wins: Int    var losses: Int    var ties: Int    func isPrizable() -> Bool{        return wins > 1    }}var basketballTeamRecord = BasketballRecord(wins: 2, losses: 10)var baseballTeamRecord = BaseballRecord(wins: 10, losses: 5)var footballTeamRecord = FootballRecord(wins: 1, losses: 1, ties: 1)//这里表面传递进来的one不仅要遵守Prizable协议还要遵守CustomStringConvertible协议func award(one: protocol<CustomStringConvertible, Prizable>){    if one.isPrizable(){        print(one)        print("Congratulation! You won a prize!")    }    else{        print(one)        print("You can not have the prize!")    }}award(baseballTeamRecord)struct Student: CustomStringConvertible, Prizable{//description是CustomStringConvertible必须实现的属性    var name: String    var score: Int    var description: String{        return name    }    func isPrizable() -> Bool {        return score >= 60    }}let liuyubobobo = Student(name: "liuyubobobo", score: 100)award(liuyubobobo)

四:泛型约束

protocol Prizable{    func isPrizable() -> Bool}struct Student: CustomStringConvertible, Equatable, Comparable, Prizable{    var name: String    var score: Int    var description: String{        return name + "Score: " + String(score)    }    func isPrizable() -> Bool {        return score >= 60    }}func ==(s1:Student,s2:Student) -> Bool{ return s1.score == s2.score}func <(s1:Student,s2:Student) -> Bool{ return s1.score < s2.score}let liuyubobobo = Student(name: "liuyubobobo", score: 100)let a = Student(name: "Alice", score: 80)let b = Student(name: "Bob", score: 92)let c = Student(name: "Karl", score: 85)let students = [a, b, c, liuyubobobo]//func topOne(seq:[Comparable]) -> Comparable//让大写的遵守Comparable协议,让数组元素的类型为T,<T: Comparable>就是泛型的约束,,func topOne<T: Comparable>(seq:[T]) -> T{    assert(seq.count > 0)    //如果使数组中的元素压缩成一个元素,使用结尾闭包    return seq.reduce(seq[0]){ max( $0 , $1 ) }}topOne([4,5,7,2])topOne(["Hello","Swift"])topOne([a,b,c,liuyubobobo])//让大写的遵守Comparable协议,让数组元素的类型为T,<T: protocol<Comparable, Prizable>>就是协议聚合的泛型约束,,func topPrizableOne<T: protocol<Comparable, Prizable>>(seq:[T]) -> T?{    return seq.reduce(nil){ ( tmpTop: T? , contender: T) in        guard contender.isPrizable() else{            return tmpTop        }        guard let tmpTop = tmpTop else{            return contender        }        return max( tmpTop , contender )   }}topPrizableOne(students)?.name

五:swift是面向协议的编程语言

/** 根据swift语言中标准库的统计:Classes: 6 个Enum: 8 个Structs: 103 个Protocol: 86 个 */var a: Int = 3var arr: Array<Int> = [1,2,3]

六:UIKit中的委托模式

这个例子用uitableview引出

七:创建自己的委托模式

protocol TurnBasedGameDelegate{    func gameStart()    func playerMove()    func gameEnd()    func gameOver() -> Bool}protocol TurnBasedGame{    var turn: Int{get set}    func play()}//这个类完成了整个游戏的过程,但是不知道游戏的细节部分,那么在具体的玩这个游戏的时候,我们就不要担心这个游戏到底是怎么一个过程,只是说明这个游戏怎么玩就是了class SinglePlayerTurnBasedGame: TurnBasedGame{    var delegate:TurnBasedGameDelegate!    var turn = 0    func play(){        delegate.gameStart()//游戏开始        while !delegate.gameOver() {//知道什么时候结束            print("ROUND",turn,":")            delegate.playerMove()//玩家开始动作            turn += 1        }        delegate.gameEnd()    }}class RollNumberGame: SinglePlayerTurnBasedGame, TurnBasedGameDelegate{    var score = 0    override init() {        super.init()//先调用父类的构造函数,初始化父类的属性        delegate = self//再初始化自己属性    }    func gameStart() {        score = 0        turn = 0        print("Welcome to Roll Number Game.")        print("Try to use least turn to make total 100 scores!")    }    func playerMove() {        let rollNumber = Int(arc4random())%6 + 1        score += rollNumber        print("You rolled a" , rollNumber , "! The score is",score,"now!")    }    func gameEnd() {        print("Congratulation! You win the game in" , turn , "ROUND!")    }    func gameOver() -> Bool{        return score >= 30    }}let rollingNumber = RollNumberGame()rollingNumber.play()class RockPaperScissors: SinglePlayerTurnBasedGame, TurnBasedGameDelegate{    enum Shape: Int, CustomStringConvertible{        case Rock        case Scissors        case Papper        func beat(shape: Shape) -> Bool{            return (self.rawValue + 1)%3 == shape.rawValue        }        var description: String{            switch(self){            case .Papper:   return "Paper"            case .Rock:     return "Rock"            case .Scissors: return "Scissors"            }        }    }    var wins = 0    var otherWins = 0    override init() {        super.init()        delegate = self    }    static func go() -> Shape{        return Shape(rawValue: Int(arc4random())%3)!    }    func gameStart() {        wins = 0        otherWins = 0        print("== Rock Paper Scissor ==")    }    func gameOver() -> Bool {        //return turn >= 3        return wins >= 2 || otherWins >= 2    }    func gameEnd() {        if( wins >= 2 ){            print("YOU WIN!")        }        else{            print("YOU LOSE...")        }    }    func playerMove() {        let yourShape = RockPaperScissors.go()        let otherShape = RockPaperScissors.go()        print("Your:",yourShape)        print("Other:",otherShape)        if yourShape.beat(otherShape){            print("You win this round")            wins += 1        }        else if otherShape.beat(yourShape){            print("You lose this round")            otherWins += 1        }        else{            print("Tie in this round")        }    }}let rockPaperScissors = RockPaperScissors()rockPaperScissors.play()

八:可选的协议方法

//如果协议中有可选型的方法,那么在协议前必须加上@objc关键字,那么这个协议就能被OC语言应用@objc protocol TurnBasedGameDelegate{    func gameStart()    func playerMove()    func gameEnd()    optional func turnStart()    optional func turnEnd()    func gameOver() -> Bool}protocol TurnBasedGame{    var turn: Int{get set}    func play()}//那么这个父类也要继承object-cclass SinglePlayerTurnBasedGame: NSObject, TurnBasedGame{    var delegate:TurnBasedGameDelegate!    var turn = 0    func play(){        delegate.gameStart()        while !delegate.gameOver() {            //如果一个函数是可选型的函数,那么这个函数就要解包            if let turnStart = delegate.turnStart{                turnStart()            }            else{                print("Round",turn,":")            }            delegate.playerMove()            //这里也需要解包,如果解包成功了就调用这个函数,如果解包失败就什么事也不做            delegate.turnEnd?()            turn += 1        }        delegate.gameEnd()    }}class RockPaperScissors: SinglePlayerTurnBasedGame, TurnBasedGameDelegate{    enum Shape: Int, CustomStringConvertible{        case Rock        case Scissors        case Papper        func beat(shape: Shape) -> Bool{            return (self.rawValue + 1)%3 == shape.rawValue        }        var description: String{            switch(self){            case .Papper:   return "Paper"            case .Rock:     return "Rock"            case .Scissors: return "Scissors"            }        }    }    var wins = 0    var otherWins = 0    override init() {        super.init()        delegate = self    }    static func go() -> Shape{        return Shape(rawValue: Int(arc4random())%3)!    }    @objc func gameStart() {//        wins = 0        otherWins = 0        print("== Rock Paper Scissor ==")    }    func gameOver() -> Bool {        return wins >= 2 || otherWins >= 2    }    func gameEnd() {        if( wins >= 2 ){            print("YOU WIN!")        }        else{            print("YOU LOSE...")        }    }    func playerMove() {        let yourShape = RockPaperScissors.go()        let otherShape = RockPaperScissors.go()        print("Your:",yourShape)        print("Other:",otherShape)        if yourShape.beat(otherShape){            print("You win this round")            wins += 1        }        else if otherShape.beat(yourShape){            print("You lose this round")            otherWins += 1        }        else{            print("Tie in this round")        }    }    func turnStart() {        print("*** ROUND START ***")    }    func turnEnd(){        print("*******************")    }}let rockPaperScissors = RockPaperScissors()rockPaperScissors.play()
1 0
原创粉丝点击