iOS --- 面向协议的编程(swift2.3)
2016-07-04 14:28
537 查看
iOS — 面向协议的编程(swift)
下面简单的介绍面向协议的编程的应用扩展协议和默认实现
面向协议编程
协议聚合
泛型约束
swift是面向协议的编程语言
UIKit中的委托模式
创建自己的委托模式
可选的协议方法
一:扩展协议和默认实现
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.gamePlayed baseballTeamRecord.gamePlayed let footballTeamRecord = FootballRecord(wins: 1, losses: 1, ties: 1) footballTeamRecord.gamePlayed footballTeamRecord.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 = 3 var 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-c class 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()
相关文章推荐
- Swift的基础之关于“!”和“?”的使用介绍
- Swift的基础之关于“!”和“?”的使用介绍
- Swift学习第十三枪-使用Swift开发IOS中蓝牙4.0的开发流程
- Swift的基础之UILabel控件
- Swift的基础之UILabel控件
- Learning Swift 3.0 - 从精通到重新入门
- 一个swift程序员寻找进阶之路
- (swift)UICollectionView方法/属性详解
- Swift 3 中的新特性
- Swift3中方法可变参数语法的一些改变
- Swift3中方法可变参数语法的一些改变
- Swift3中方法可变参数语法的一些改变
- Swift3中方法可变参数语法的一些改变
- Swift3中方法可变参数语法的一些改变
- Swift3中方法可变参数语法的一些改变
- swift中与js交互
- iOS --- 协议部分(swift2.3)
- iOS --- 如何在Swift项目中使用runtime?
- swift6-元祖
- Swift开发小技巧--识别选中照片中的二维码