swift学习日记(十一)



一,协议

协议听起来挺高大上,其实就对应着 c++ 里面的基类

协议提供了一系列的方法和属性,但是并不实现它,只是对其名称等进行一个规范,其他类/结构体/枚举 都可以继承协议,并实现其中的功能,称之为遵循者

protocol SomeProtocol {
    // 协议内容
}
class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol {
    // 类的内容
}

一个类可以继承多个协议,也可以同时继承父类和协议


1,协议的属性

protocol SomeProtocol {
    var musBeSettable : Int { get set }
    var doesNotNeedToBeSettable: Int { get } //可读,未规定是否可写
}

前面说到,协议是不实现具体功能的,但是可以标明属性的读写属性,如果只有get,说明是可读属性,但是并不代表只读,如果其他类实现了写的功能,那也不会报错

遵循者中,可以对协议中的属性进行扩展,但是必须完整地实现协议中所有属性方法,不能少,否则会报错


2,协议的方法

协议方法支持变长参数(variadic parameter),不支持默认参数(default parameter)。

文档中有这么一句话:前置class关键字表示协议中的成员为类成员;当协议用于被枚举或结构体遵循时,则使用static关键字。

不过经我测试,似乎swift2中已经不支持协议的类成员了,一律都得用static。

当然,如果什么都不加也行,只是标明是个方法

protocol SomeProtocol {
    static func someTypeMethod()
}

protocol RandomNumberGenerator {
    func random() -> Double
}
class LinearCongruentialGenerator: RandomNumberGenerator {
    var lastRandom = 42.0
    let m = 139968.0
    let a = 3877.0
    let c = 29573.0
    func random() -> Double {
        lastRandom = ((lastRandom * a + c) % m)
        return lastRandom / m
    }
}
let generator = LinearCongruentialGenerator()
println("Here's a random number: \(generator.random())")
// 输出 : "Here's a random number: 0.37464991998171"
println("And another one: \(generator.random())")
// 输出 : "And another one: 0.729023776863283"

3,突变方法

协议是可能被结构体和枚举 遵循的,但是在结构体/枚举 中,方法是不能改变属性的

如果协议中的方法可能在未来需要改变其他属性,就需要加上mutating

当然,类在遵循协议的时候,不需要加mutating,因为类本来就可以改

protocol Togglable {
    mutating func toggle()
}
enum OnOffSwitch: Togglable {
    case Off, On
    mutating func toggle() {
        switch self {
        case Off:
            self = On
        case On:
            self = Off
        }
    }
}
var lightSwitch = OnOffSwitch.Off
lightSwitch.toggle()
//lightSwitch 现在的值为 .On


4,协议类型

虽然协议不实现任何功能,但是协议同样可以当作一个类型来使用,如果一个变量的类型为一个协议,那么它可以被赋值为任何遵循它的类型

class Dice {
    let sides: Int
    let generator: RandomNumberGenerator
    init(sides: Int, generator: RandomNumberGenerator) {
        self.sides = sides
        self.generator = generator
    }
    func roll() -> Int {
        return Int(generator.random() * Double(sides)) +1
    }
}

如上,generator由于为RandomNumberGenerator的协议类型。所以它能够被赋值为任意遵循该协议的类型

也就是说,我们在这个类里只是给了一个接口,具体怎么样去实现这个功能,需要调用这个接口的开发者去完成。

这个功能是不是就像是c++11的函数指针


5,委托/代理模式

委托这是在类java语言中非常常用的特性


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值