Protocols - 完成 提供默认实现

This commit is contained in:
futantan
2015-07-09 11:04:43 +08:00
parent 8432bd90ad
commit 648b809c20

View File

@ -58,7 +58,7 @@ class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol {
协议可以规定其`遵循者`提供特定名称和类型的`实例属性(instance property)``类属性(type property)`,而不指定是`存储型属性(stored property)`还是`计算型属性(calculate property)`。此外还必须指明是只读的还是可读可写的。 协议可以规定其`遵循者`提供特定名称和类型的`实例属性(instance property)``类属性(type property)`,而不指定是`存储型属性(stored property)`还是`计算型属性(calculate property)`。此外还必须指明是只读的还是可读可写的。
如果协议要求属性是可读可写的,那么这个属性不能是常量或只读的计算属性。如果协议只要求属性是只读的(gettable),那个属性不仅可以是只读的,如果你代码需要的话,也可以是可写的。 如果协议规定属性是可读可写的,那么这个属性不能是常量或只读的计算属性。如果协议只要求属性是只读的(gettable),那个属性不仅可以是只读的,如果你代码需要的话,也可以是可写的。
协议中的通常用var来声明属性在类型声明后加上`{ set get }`来表示属性是可读可写的,只读属性则用`{ get }`来表示。 协议中的通常用var来声明属性在类型声明后加上`{ set get }`来表示属性是可读可写的,只读属性则用`{ get }`来表示。
@ -835,9 +835,9 @@ for _ in 1...5 {
<a name="protocol_extensions"></a> <a name="protocol_extensions"></a>
## 协议扩展 ## 协议扩展
Protocols can be extended to provide method and property implementations to conforming types. This allows you to define behavior on protocols themselves, rather than in each types individual conformance or in a global function. 使用扩展协议的方式可以为遵循者提供方法或属性的实现。通过这种方式,可以让你无需在每个遵循者中都实现一次,无需使用全局函数,你可以通过扩展协议的方式进行定义。
For example, the `RandomNumberGenerator` protocol can be extended to provide a `randomBool()` method, which uses the result of the required `random()` method to return a random `Bool` value: 例如,可以扩展`RandomNumberGenerator`协议,让其提供`randomBool()`方法。该方法使用协议中要求的`random()`方法来实现:
```swift ```swift
extension RandomNumberGenerator { extension RandomNumberGenerator {
@ -847,24 +847,24 @@ extension RandomNumberGenerator {
} }
``` ```
By creating an extension on the protocol, all conforming types automatically gain this method implementation without any additional modification. 通过扩展协议,所有协议的遵循者,在不用任何修改的情况下,都自动得到了这个扩展所增加的方法。
```swift ```swift
let generator = LinearCongruentialGenerator() let generator = LinearCongruentialGenerator()
print("Here's a random number: \(generator.random())") print("Here's a random number: \(generator.random())")
// prints "Here's a random number: 0.37464991998171" // 输出 "Here's a random number: 0.37464991998171"
print("And here's a random Boolean: \(generator.randomBool())") print("And here's a random Boolean: \(generator.randomBool())")
// prints "And here's a random Boolean: true" // 输出 "And here's a random Boolean: true"
``` ```
### Providing Default Implementations ### 提供默认实现
You can use protocol extensions to provide a default implementation to any method or property requirement of that protocol. If a conforming type provides its own implementation of a required method or property, that implementation will be used instead of the one provided by the extension. 可以通过协议扩展的方式来为协议规定的属性和方法提供默认的实现。如果协议的遵循者对规定的属性和方法提供了自己的实现,那么遵循者提供的实现将被使用。
> NOTE > 注意
> Protocol requirements with default implementations provided by extensions are distinct from optional protocol requirements. Although conforming types dont have to provide their own implementation of either, requirements with default implementations can be called without optional chaining. > 通过扩展协议提供的协议实现和可选协议规定有区别。虽然协议遵循者无需自己实现,通过扩展提供的默认实现,可以不是用可选链调用。
For example, the `PrettyTextRepresentable` protocol, which inherits the `TextRepresentable` protocol can provide a default implementation of its required `asPrettyText()` method to simply return the result of the `asText()` method: 例如,`PrettyTextRepresentable`协议,继承了`TextRepresentable`协议,可以为其提供一个默认的`asPrettyText()`方法来简化返回值
```swift ```swift
extension PrettyTextRepresentable { extension PrettyTextRepresentable {
@ -874,11 +874,11 @@ extension PrettyTextRepresentable {
} }
``` ```
### Adding Constraints to Protocol Extensions ### 为协议扩展添加限制条件
When you define a protocol extension, you can specify constraints that conforming types must satisfy before the methods and properties of the extension are available. You write these constraints after the name of the protocol youre extending using a `where` clause, as described in ([Where 子句](TODO)).: 在扩展协议的时候,可以指定一些限制,只有满足这些限制的协议遵循者,才能获得协议扩展提供的属性和方法。这些限制写在协议名之后,使用`where`关键字来描述限制情况。([Where 子句](TODO)):
For instance, you can define an extension to the `CollectionType` protocol that applies to any collection whose elements conform to the `TextRepresentable protocol` from the example above. 例如,你可以扩展`CollectionType`协议,但是只适用于元素遵循`TextRepresentable`的情况:
```swift ```swift
extension CollectionType where Generator.Element : TextRepresentable { extension CollectionType where Generator.Element : TextRepresentable {
@ -888,9 +888,9 @@ extension CollectionType where Generator.Element : TextRepresentable {
} }
``` ```
The `asList()` method takes the textual representation of each element in the collection and concatenates them into a comma-separated list. `asList()`方法将每个元素以`asText()`的方式表示,最后以逗号分隔链接起来。
Consider the `Hamster` structure from before, which conforms to the `TextRepresentable` protocol, and an array of `Hamster` values: 现在我们来看`Hamster`,它遵循`TextRepresentable`:
```swift ```swift
let murrayTheHamster = Hamster(name: "Murray") let murrayTheHamster = Hamster(name: "Murray")
@ -899,12 +899,12 @@ let mauriceTheHamster = Hamster(name: "Maurice")
let hamsters = [murrayTheHamster, morganTheHamster, mauriceTheHamster] let hamsters = [murrayTheHamster, morganTheHamster, mauriceTheHamster]
``` ```
Because `Array` conforms to `CollectionType`, and the arrays elements conform to the `TextRepresentable` protocol, the array can use the `asList()` method to get a textual representation of its contents: 因为`Array`遵循`CollectionType`协议,数组的元素又遵循`TextRepresentable`协议,所以数组可以使用`asList()`方法得到数组内容的文本表示:
```swift ```swift
print(hamsters.asList()) print(hamsters.asList())
// prints "(A hamster named Murray, A hamster named Morgan, A hamster named Maurice)" // 输出 "(A hamster named Murray, A hamster named Morgan, A hamster named Maurice)"
``` ```
> NOTE > 注意
> If a conforming type satisfies the requirements for multiple constrained extensions that provide implementations for the same method or property, Swift will use the implementation corresponding to the most specialized constraints. > 如果有多个协议扩展,而一个协议的遵循者又同时满足它们的限制,那么将会使用所满足限制最多的那个扩展。