Swift 协议
2017-11-23 本文已影响12人
追逐_chase
Swift.png
协议的简单介绍
- 规定了用来实现某一特定任务或者功能的方法、属性,以及其他需要的东西
- 类、结构体 或枚举都可以遵循协议,并为协议定义的这些要求提供具体实现(必须要实现协议的属性或者方法)
- 协议的格式:协议的定义方式与类、结构体和枚举的定义非常相似
protocol SomeProtocol {
// 这里是协议的定义部分
}
- 要让自定义类型遵循某个协议,在定义类型时,需要在类型名称后加上协议名称,中间以冒号( : )分隔。遵循 多个协议时,各协议之间用逗号( , )分隔
struct SomeStructure: FirstProtocol, AnotherProtocol { // 这里是结构体的定义部分
}
- 拥有父类的类在遵循协议时,应该将父类名放在协议名之前,以逗号分隔
class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol { // 这里是类的定义部分
}
- 协议是可以继承的,一个协议可以继承另外一个协议
属性的要求
- 协议可以要求遵循协议的类型提供特定名称和类型的实例属性或类型属性。
- 协议不指定属性是存储型属性还是计算型属性,它只指定属性的名称和类型。
- 协议还指定属性是可读的还是可读可写的。
- 如果协议要求属性是可读可写的,那么该属性不能是常量属性或只读的计算型属性
- 如果协议只要求属性是可读的,那么该属性不仅可以是可读的,如果代码需要的话,还可以是可写的。
- 协议总是用 var 关键字来声明变量属性,在类型声明后加上 { set get } 来表示属性是可读可写的,可读属性则用 { get } 来表示
protocol SomeProtocol {
var mustBeSettable: Int { get set }
var doesNotNeedToBeSettable: Int { get }
}
- 在声明 类型属性的时候可以使用 static或者 class关键字
//例子
//定义一个协议
protocol Work{
var type:String {get set}
var name:String {get set}
}
struct Type:Work{
//类型必须声明协议里面的属性
var type: String;
var name: String;
}
//结构体有逐一构造器
let t = Type(type: "互联网", name: "IT部门");
t.type
t.name
//打印:"互联网" "IT部门"
方法
- 协议可以要求遵循协议的类型实现某些指定的实例方法或类方法
- 协议里面定义的方法不需要大括号和方法体
- 用 static或者class定义类型方法
//定义一个协议
protocol Run {
func directionRun();
}
//定义一个枚举
enum Direction:Run {
case left
case right
case up
case down
func directionRun() {
print("跑的方向")
}
}
Direction.left.directionRun();
- 将 mutating 关键 字作为方法的前缀,写在 func 关键字之前,表示可以在该方法中修改它所属的实例以及实例的任意属性的值(在值类型中,主要是结构体和枚举中)
- Mutating 方法:需要在方法中改变方法所属的实例
- 如果遵循协议的是 类 则不用写 mutating 关键字,而对于结构体和枚举,则必须写
mutating 关键字。
//定义一个协议
protocol Togglable {
mutating func toggle()
}
//定义一个枚举 遵循协议Togglable
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
构造器
- 协议可以要求遵循协议的类型实现指定的构造器
protocol SomeProtocol {
init(someParameter: Int)
}
- 你可以在遵循协议的类中实现构造器,无论是作为指定构造器,还是作为便利构造器。无论哪种情况,你都必须 为构造器实现标上 required 修饰符
class SomeClass: SomeProtocol {
required init(someParameter: Int) {
// 这里是构造器的实现部分 }
}
-
如果类已经被标记为 final ,那么不需要在协议构造器的实现中使用 required 修饰符,因为 final 类不能有子类
-
如果一个子类重写了父类的指定构造器,并且该构造器满足了某个协议的要求,那么该构造器的实现需要同时标 注 required 和 override 修饰符
protocol SomeProtocol {
init()
}
class SomeSuperClass {
init() {
// 这里是构造器的实现部分
}
}
class SomeSubClass: SomeSuperClass, SomeProtocol { // 因为遵循协议,需要加上 required
// 因为继承自父类,需要加上 override
required override init() {
// 这里是构造器的实现部分
}
}
代理
- 代理(委托)是一种设计模式,允许类或结构体将一些需要它们负责的功能委托给其他类型的实例
//协议:遵循class类 方便delege属性 weak
protocol Work:class {
func test();
}
//工作的员工
class Person:Work {
func test() {
print("开始工作");
}
}
//宠物狗
class Dog: Work {
func test() {
print("旺旺")
}
}
//老板
class Master {
//weak:是修饰 类类型的
weak var delegate:Work?
}
let M = Master();
//设置代理
M.delegate = Dog();
M.delegate?.test()
让协议的方法可选
- 在OC的协议中方法可以实现也可以不实现,但是在Swift中的协议中 方法必须要实现,解决方法 方swift中的协议 转化成OC 中协议
@objc
protocol Work {
//可选择实现 方法
@objc optional func test();
}
class Person:Work {
}