import Foundation
/
/
//_______________________________________________________________________________________________
//定义一个 Dice 类以备后用(协议做属性类型,协议做构造器参数类型)
class Dice{
let sides: Int
let generator: RandomNumberGenerator //Dice 含有 sides 和 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: LinerCongruentialGenerator())
for _ in 1...5{
println("Random dice roll is \(d6.roll())")
}
//***********************************************************************************************
//7.Delegation(委托代理模式)
//_______________________________________________________________________________________________
//委托是一种模式,它允许类或结构体将一些需要他们负责的功能交由给其他的类型
//委托模式的实现很简单:定义协议来封装那些需要被委托的函数和方法,使其遵循者拥有这些被委托的函数和方法
//_______________________________________________________________________________________________
//实例代码演示委托
protocol DiceGame{ //DiceGame 为实现游戏的协议
var dice: Dice {get}
func paly()
}
protocol DiceGameDelegate{ //DiceGameDelegate 为跟踪游戏过程
func gameDidStart(game: DiceGame)
func game(game: DiceGame, didStartNewTurnWithDiceRoll diceRoll: Int)
func gameDidEnd(game: DiceGame)
}
class SnakesAndLadders: DiceGame{ //定义 SnakesAndLadders 遵守协议 DiceGame
let finalSquare = 25
let dice = Dice(sides: 6, generator: LinerCongruentialGenerator()) //满足协议 DiecGame 的属性
var square = 0
var board: [Int]
init(){
board = [Int](count: finalSquare + 1, repeatedValue: 0)
board[03] = +08
board[06] = +11
board[09] = +09
board[10] = +02
board[24] = -08
board[14] = -10
board[19] = -11
board[22] = -02
}
var delegate: DiceGameDelegate? //因为 delegate 是一个遵循 DiceGameDelegate 协议的可选属性类型,因此在 play()方法中使用了可选链来调用委托方法。若 delegate 属性为 nil, 则委托调用优雅地失效。若 delegate 不为nil,则委托方法被调用
func paly(){ //满足协议 DiceGame 的方法
delegate?.gameDidEnd(self) //通过代理使用 DiceGameDelegate 协议中的方法
delegate?.game(self, didStartNewTurnWithDiceRoll: 1)
delegate?.gameDidStart(self)
}
}
class DiceGameTracker: DiceGameDelegate{ //DiceGameTracker 实现了 DiceGameDelegate 协议的方法要求
var numberOfTurns = 0
func gameDidStart(game: DiceGame) { //满足协议 DiceGameDelegate 的方法
if game is SnakesAndLadders{
println("Started a new game of Snakes and Ladders")
}
println("The game is using a \(game.dice.sides) - sided dice")
}
func game(game: DiceGame, didStartNewTurnWithDiceRoll diceRoll:Int){ //满足协议 DiceGameDelegate 的方法
++numberOfTurns
println("Rolled a \(diceRoll)")
}
func gameDidEnd(game: DiceGame){ //满足协议的方法
println("The game lasted for \(numberOfTurns) turns")
}
}
let tracker = DiceGameTracker()
let game = SnakesAndLadders()
game.delegate = tracker //给 SnakesAndLadders 类型的实例的 .delegate 赋值让它不为 nil 时,便可以在 SnakesAndLadders 实例中使用 DiceGameDelegate 协议内的方法
game.paly()
//***********************************************************************************************
//8.Adding Protocol Conformance with an Extension(在扩展中添加协议成员)
//_______________________________________________________________________________________________
//介绍
//即使无法修改源代码,依然可以通过扩展来扩充已存在类型
//_______________________________________________________________________________________________
//实例代码演示在扩展中添加协议成员
protocol TextRepresentable{ //定义一个协议
func asText() -> String
}
extension Dice: TextRepresentable{ //给 Dice 协议扩展功能
func asText() -> String{
return "A \(sides) - side dice"
}
}
let d12 = Dice(sides: 12, generator: LinerCongruentialGenerator())
println(d12.asText()) //这是我们可以使用扩展过后的协议的方法
//_______________________________________________________________________________________________
//通过扩展补充协议声明
struct Hamster{
var name: String
func asText() -> String{
return "A hamster named \(name)"
}
}
extension Hamster: TextRepresentable{} //当一个类型已经实现了协议中的所有要求,却没有声明时,可以通过扩展来补充协议声明
let simonTheHamster = Hamster(name: "Simon")
let somethingTextRepresentable: TextRepresentable = simonTheHamster
println(somethingTextRepresentable.asText())
//***********************************************************************************************
//9.Collections of Protocol Types(集合中的协议类型)
//_______________________________________________________________________________________________
//协议可以被集合使用,表示集合中的元素均为协议类型
let things: [TextRepresentable] = [d12, simonTheHamster]
for thing in things{
println(thing.asText())
}
//***********************************************************************************************
//10.Protocol Inheritance(协议的继承)
//_______________________________________________________________________________________________
//介绍
//协议能够继承一到多个其他的协议,语法与类的继承相似
//_______________________________________________________________________________________________
//实例代码演示协议的继承
protocol PrettyTextRepresentable: TextRepresentable{ //PrettyTextRepresentable 协议继承l了TextRepresentable 协议,遵循 PrettyTextRepresentable 协议的同时,也需要遵循 TextRepresentable 的协议
func asPrettyText() -> String
}
extension SnakesAndLadders: PrettyTextRepresentable { //用扩展为 SnakesAndLadders 遵循PrettyTextRepresentable 协议
func asPrettyText() -> String { //遵守 PrettyTextRepresentable 协议中的方法
var output = "Hello" + ":\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
}
func asText() -> String{ //遵守 TextRepresentable 协议中的方法
return "Listo"
}
}
println(game.asPrettyText())
println(game.asText())
//***********************************************************************************************
//11.Protocol Composition(协议的合成)
//_______________________________________________________________________________________________
//实例代码演示协议的合成
protocol Named{ //Named 协议包含 String 类型的 name 属性
var name: String {get}
}
protocol Aged{ //Aged 协议包含 Int 类型的 age 属性
var age: Int {get}
}
struct Person1: Named, Aged{ //Person 结构体遵循了这两个协议
var name: String
var age: Int
}
func wishHappyBirthday(celebrator: protocol<Named, Aged>){ //wishHappyBirthday 函数的形参 celebrator 的类型为 protocol<Named,Aged>。可以传入任 意遵循这两个协议的类型的实例
println("Happy birthday \(celebrator.name) - you're \(celebrator.age)")
}
let birthdayPerson = Person1(name: "Pin", age: 21)
wishHappyBirthday(birthdayPerson)
//***********************************************************************************************
//12.Checking for Protocol Conformance(检查协议的一致性)
//_______________________________________________________________________________________________
//使用 is 检查协议的一致性,使用 as 将协议类型向下转换为其他的协议类型(is 判断某个类型是否遵守协议,as? 返回一个可选值,当实例遵守协议时,返回协议类型,否则为 nil,as 用以强制向下转化
//_______________________________________________________________________________________________
//实例代码演示检查协议的一致性
@objc protocol HasArea{ //这里的 @objc 用来表示协议是可选的,@objc 型协议只对类有效,只能检查类中协议的一致性
var area: Double {get}
}
class Circle: HasArea {
let pi = 3.1415927
var radius: Double
var area: Double { //Circle 遵守协议 HasArea,并且把 area 写成计算型属性
return pi * radius * radius
}
init(radius: Double) {
self.radius = radius
}
}
class Country: HasArea { //Country 遵守协议 HasArea,并且把 area 写成存储型属性
var area: Double
init(area: Double) { self.area = area }
}
class Animal{ //Animal 不遵守任何协议
var legs: Int
init(legs: Int) {
self.legs = legs
}
}
let objects: [AnyObject] = [ //Circle,Country,Animal 并没有相同的父类,所以使用 Anyobject 来装载他们的实例
Circle(radius: 2.0),
Country(area: 242_455),
Animal(legs: 4)
]
for object in objects{
if let objectWithArea = object as? HasArea{ //当数组中的元素遵循 HasArea 协议时,通过 as?操作符将其可选绑定(optional binding)到 objectWithArea 常量上
println("Area is \(objectWithArea.area)")
}
else{
println("Something that doesn't have an area")
}
}
//***********************************************************************************************
//13.Optional Protocol Requirements(可选协议要求)
//_______________________________________________________________________________________________
//介绍
//可选协议含有可选成员,其遵循者可以选择是否实现这个可选成员,在协议中使用 @optional 关键字作为前缀来定义可选成员
//_______________________________________________________________________________________________
//实例代码演示可选协议的使用
@objc protocol CounterDataSource{
@optional func incrementForCount(count: Int) -> Int //定义协议可选方法
@optional var fixedIncrement: Int {get} //定义协议可选属性
}
@objc class Counter{
var count = 0
var dataSource: CounterDataSource?
func increment(){
if let amount = dataSource?.incrementForCount?(count){ //由于 dataSource 可能为 nil,因此在 dataSource 后边加上了?标记来表明只在 dataSource 非空时才去调用 incrementForCount 方法,即使 dataSource 存在,但是也无法保证其是否实现了 incrementForCount 方法,因此在 incrementForCount 方法后边也加有?标记
count += amount
}
else if let amount = dataSource?.fixedIncrement?{ //当 incrementForCount 不能被调用时,尝试使用可选属性 fixedIncrement 来代替(代理)
count += amount
}
}
}
class ThreeSource: CounterDataSource{ //ThreeSource 实现了 CounterDataSource 协议
let fixedIncrement = 3
}
var counter = Counter()
counter.dataSource = ThreeSource() //使用 ThreeSource 作为数据源开实例化一个 Counter
for _ in 1...4{
counter.increment()
println(counter.count)
}
class TowardsZeroSource: CounterDataSource{ //TowardsZeroSource 实现了 CounterDataSource 协议中的 incrementForCount 方法
func incrementForCount(count: Int) -> Int {
if count == 0{
return 0
}
else if count < 0{
return 1
}
else{
return -1
}
}
}
counter.count = -4
counter.dataSource = TowardsZeroSource()
for _ in 1...5{
counter.increment()
println(counter.count)
}