协议基础
关于协议
协议指定符合协议的 Swift 对象类型(类,结构或枚举)所需的初始化程序,属性,函数,下标和关联类型。在某些语言中,后续对象的需求规范的类似想法被称为接口。
声明和定义的协议是一个类型本身,具有其声明要求的签名,有点类似于 Swift 函数是基于其参数和返回的签名的类型的方式。
Swift 协议规范可以是可选的,明确要求和/或通过称为协议扩展的工具给定默认实现。Swift 对象类型(类,结构或枚举)希望符合使用 Extensions 满足其所有指定要求的协议,只需说明其符合完全一致性的要求。Protocol Extensions 的默认实现工具足以履行符合协议的所有义务。
协议可以由其他协议继承。这与 Protocol Extensions 结合使用,意味着 Protocols 可以而且应该被认为是 Swift 的一个重要特性。
协议和扩展对于实现 Swift 更广泛的程序设计灵活性和开发过程的目标和方法非常重要。Swift 的协议和扩展功能的主要目的是促进程序架构和开发中的组合设计。这被称为面向协议的编程。坚硬的老计时器认为这优于对 OOP 设计的关注。
protocol MyProtocol {
init(value: Int) // required initializer
func doSomething() -> Bool // instance method
var message: String { get } // instance read-only property
var value: Int { get set } // read-write instance property
subscript(index: Int) -> Int { get } // instance subscript
static func instructions() -> String // static method
static var max: Int { get } // static read-only property
static var total: Int { get set } // read-write static property
}
协议中定义的属性必须注释为 { get }
或 { get set }
。{ get }
意味着该属性必须是 gettable,因此它可以实现为任何类型的属性。{ get set }
意味着该属性必须既可以设定也可以获得。
结构,类或枚举可以符合协议:
struct MyStruct : MyProtocol {
// Implement the protocol's requirements here
}
class MyClass : MyProtocol {
// Implement the protocol's requirements here
}
enum MyEnum : MyProtocol {
case caseA, caseB, caseC
// Implement the protocol's requirements here
}
协议还可以通过扩展来定义其任何需求的默认实现 :
extension MyProtocol {
// default implementation of doSomething() -> Bool
// conforming types will use this implementation if they don't define their own
func doSomething() -> Bool {
print("do something!")
return true
}
}
协议可以用作类型,只要它没有 associatedtype
要求 :
func doStuff(object: MyProtocol) {
// All of MyProtocol's requirements are available on the object
print(object.message)
print(object.doSomething())
}
let items : [MyProtocol] = [MyStruct(), MyClass(), MyEnum.caseA]
你还可以定义符合多个协议的抽象类型 :
Version >= 3.0
使用 Swift 3 或更高版本,可以通过使用&符号(&
)分离协议列表来完成:
func doStuff(object: MyProtocol & AnotherProtocol) {
// ...
}
let items : [MyProtocol & AnotherProtocol] = [MyStruct(), MyClass(), MyEnum.caseA]
Version < 3.0
旧版本具有语法 protocol<...>
,其中协议是尖括号 <>
之间的逗号分隔列表。
protocol AnotherProtocol {
func doSomethingElse()
}
func doStuff(object: protocol<MyProtocol, AnotherProtocol>) {
// All of MyProtocol & AnotherProtocol's requirements are available on the object
print(object.message)
object.doSomethingElse()
}
// MyStruct, MyClass & MyEnum must now conform to both MyProtocol & AnotherProtocol
let items : [protocol<MyProtocol, AnotherProtocol>] = [MyStruct(), MyClass(), MyEnum.caseA]
可以扩展现有类型以符合协议:
extension String : MyProtocol {
// Implement any requirements which String doesn't already satisfy
}