你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS --- 面向協議的編程(swift2.3)

iOS --- 面向協議的編程(swift2.3)

編輯:IOS開發綜合

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){

    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,就是泛型的約束,,
func topOne(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,>就是協議聚合的泛型約束,,
func topPrizableOne>(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 = [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()
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved