.
Protocol is name type, structs ,classes, and enums also name type. A protocol can be adopted by a class, struct, or enum
.
Swift中默认所有的方法都是必须实现是的
1 | protocal Vehicle { |
- 协议可以被
class
、struct
、enum
所遵守。 - 协议里的方法不能包含默认值。
- 如果要定义
Optional
的值,需要提供两个方法。fun turn()
和fun turn(_ value:valueType)
Protocol inheritance
1 | protocol WheeledVehicle: Vehicle { |
Implementing properties
当协议里面定义必须实现的值的get
或者set
方法。该值既可以是stored property
也可以是 computed property
。而如果协议之要求你实现get
方法,你的参数可以实现get
和set
方法一起。
Associated Types in protocols
你可以用associated type
关键字来定义协议要用到的相关类型,有点类似函数的泛型
1 | protocol WeightCalculatable { |
1 | class HeavyThing: WeightCalculatable { |
我们用typealias
关键字解释WeightType
是什么类型,这个通常是不需要写的。
Implementing multiple protocols
1 | class Bike: Vehicle, Wheeled { |
Protocol Composition
In the previous section you learned how to implement multiple protocols. Sometimes you need a function to take a data type that must conform to multiple protocols. That is where protocol composition comes in. Imagine you need a function that needs access to the Vehicle protocol’s stop() function and the Wheeled protocol’s numberOfWheels property. You can do this using the & composition operator.
1 | func roundAndRound(transportation: Vehicle & Wheeled) { |
Extensions and protocol conformance
可以用类的扩展来遵守也写,即使是像String这样的类,我们也可以通过这个方法让String来遵守一些协议。
1 | protocol Reflective { |
两个好处
- 可以让一些系统类来遵守你的协议
- 可以把一些协议的实现定义在扩展里面,让代码看起来不那么乱
最近Swift版本可以在协议里面访问该类的私有变量
你不能在扩展里面定义stored properties
但是你仍然可以通过在原来的类中定义stored properties
来满足你在扩展里面协议需要实现的参数。
Requiring Reference semantics
因为协议能够被types type
(structs 和 enums)遵守和reference type
类型(classes)所遵守,所以对于structs
和classes
复制时不同的处理方式,你可能想要某些协议限制只能被classes
所遵守。
1 | protocol Named: class { |
Protocols in the standard library
Equatable
当你要用==
比对两个自定义的对象是否相等的时候,你需要是显示系统的Equatable
协议
1 | protocol Equatable { |
你需要在你的协议里面遵守该协议,如果你想比对你定义的协议是否相等,在方法里给出Bool值,来判断两个自定义的对象是否相等。
Comparable
Comparable
类似==
,提供了<
,<=
,>
和>=
来比对你自定义的对象。
你只需要实现<
和==
,其他的运算方法标准库会为你自动实现。
1 | protocol Comparable: Equatable { |
Free
functions
当你为你的类实现了==
和<
协议,那么系统会自动为你实现其他的方法例如
1 | leagueRecords.max() // {wins 23, losses 8} |
Hashable
Hashable
是Equatable
的子类,任何你要用作为Dictionary
字典的Key
都需要遵守该协议。
1 | protocol Hashable : Equatable { |
Hashable可以快速帮你在集合中找到元素,所以==
为true
的值,那么Hash
值应该是一样的。
一般用==比对的值来发挥相同的hash值,例如
student
对象里面name
,我们可以用name
来判断该学生是否为同一个学生,也可以用name
的hash值来当做整个student对象的hash值
CustomStringConvertible
CustomStringConvertible
提供你print
自定义对象时候的内容。
1 | protocol CustomStringConvertible { |
CustomDebugStringConvertibale
和CustomStringConvertible
非常相识,只是互相对应的debugPrint
和
Objective-C 中的Optional选项
对于Swift中的Optional
的值,我觉得可以在Swift中通过继承的方式来实现。
原生的Swift protocol里没有可选值,所有定义的方法都必须实现的。如果我们想要像Objective-C里那样定义可选的接口方法,就需要将接口本身定义为Objective-C的,也即在protocol定义之前加上@objc。另外和Objective-C中的@Optional不同,我们使用没有@符号的关键字optional来定义可选方法:
1 | @objc protocol viewDelegate { |