iOS --- 面向协议的编程(swift2.3)
来源:互联网 发布:雷欧mac全灭图解 编辑:程序博客网 时间:2024/05/21 22:56
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.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
- iOS --- 面向协议的编程(swift2.3)
- iOS --- 协议部分(swift2.3)
- 介绍在Swift2面向协议编程(译文)
- iOS --- 错误处理部分(swift2.3)
- iOS倒计时-swift2.3
- iOS开发:面向协议编程与 Cocoa 的邂逅 (上)
- iOS开发:面向协议编程与 Cocoa 的邂逅 (下)
- iOS开发:面向协议编程与 Cocoa 的邂逅 (上)
- IOS 工厂模式的面向协议编程思想
- iOS开发:Swift面向协议编程初探
- iOS --- 下标和计算符重载(swift2.3)
- iOS --- 扩展和泛型(swift2.3)
- iOS-Swift 面向协议编程/组件化(模块化)编程思想
- java se 面向网络的编程(IP,端口,协议)
- 面向协议编程与 Cocoa 的邂逅
- fir.im Weekly - 揭秘 iOS 面向协议编程
- Swift面向协议编程(附代码)
- 面向HTTP协议编程
- RT-thread内核之线程内核对象
- Elasticsearch java API (25)查询 DSL Span(跨度)查询
- Struts2注解使用说明
- 博主个人站点 -- CRMHOME.NET Beta版本上线啦!
- windos7中配置python的环境变量
- iOS --- 面向协议的编程(swift2.3)
- Android 即时聊天时候涉及的ListView 倒序问题
- linux之GPIO的使用------OK6410
- Git常用操作命令 (全)
- 动态计算UITableViewCell的高度
- 决策学习笔记
- 十大渗透测试演练系统
- 方正电子2016面试总结
- 微课秀