From caed8e20afec3fe4f1b1a561970f88c12599f179 Mon Sep 17 00:00:00 2001 From: oldcodeoberyn Date: Sun, 31 Aug 2014 22:17:22 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=8D=8F=E8=AE=AE=E4=B8=80?= =?UTF-8?q?=E7=AB=A0=EF=BC=8C=E6=B7=BB=E5=8A=A0=E6=96=B0=E7=9A=84=E4=B8=A4?= =?UTF-8?q?=E4=B8=AA=E5=B0=8F=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initializer requirement Class-only protocol --- source/chapter2/21_Protocols.md | 75 ++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/source/chapter2/21_Protocols.md b/source/chapter2/21_Protocols.md index b8ffb090..8e52d694 100755 --- a/source/chapter2/21_Protocols.md +++ b/source/chapter2/21_Protocols.md @@ -9,13 +9,15 @@ - [协议的语法(Protocol Syntax)](#protocol_syntax) - [对属性的规定(Property Requirements)](#property_requirements) - [对方法的规定(Method Requirements)](#method_requirements) -- [对突变方法的的规定(Mutating Method Requirements)](#mutating_method_requirements) +- [对突变方法的规定(Mutating Method Requirements)](#mutating_method_requirements) +- [对构造器的规定(Initializer Requirements)](#initializer_requirements) - [协议类型(Protocols as Types)](#protocols_as_types) - [委托(代理)模式(Delegation)](#delegation) - [在扩展中添加协议成员(Adding Protocol Conformance with an Extension)](#adding_protocol_conformance_with_an_extension) - [通过扩展补充协议声明(Declaring Protocol Adoption with an Extension)](#declaring_protocol_adoption_with_an_extension) - [集合中的协议类型(Collections of Protocol Types)](#collections_of_protocol_types) - [协议的继承(Protocol Inheritance)](#protocol_inheritance) +- [类专属协议(Class-Only Protocol)](#class_only_protocol) - [协议合成(Protocol Composition)](#protocol_composition) - [检验协议的一致性(Checking for Protocol Conformance)](#checking_for_protocol_conformance) - [对可选协议的规定(Optional Protocol Requirements)](#optional_protocol_requirements) @@ -208,6 +210,60 @@ lightSwitch.toggle() //lightSwitch 现在的值为 .On ``` + +## 对构造器的规定 + +协议可以要求它的遵循类型实现特定的构造器。你可以像书写普通的构造器那样,在协议的定义里写下构造器的需求,但不需要写花括号和构造器的实体: + +```swift +protocol SomeProtocol { + init(someParameter: Int) +} +``` + +**协议构造器规定在类中的实现** + +你可以在协议的遵循类中把协议构造器规定实现为指定构造器或者便利构造器。在这两种情况下,你都必须给构造器实现标上"required"修饰符: + +```swift +class SomeClass: SomeProtocol { + required init(someParameter: Int) { + //构造器实现 + } +} +``` + +使用`required`修饰符可以保证:所有的遵循该协议的子类,同样能为构造器规定提供一个显式的实现或继承实现。 + +关于`required`构造器的更多内容,请参考`required`构造器 + +>注意 +> +>如果类已经被“final”修饰符所标示,你就不需要在协议构造器规定的实现中使用"required"修饰符。因为final类不能有子类。关于`final`修饰符的更多内容,请参见防止重写 + +如果一个子类重写了父类的指定构造器,并且该构造器遵循了某个协议的规定,那么该构造器的实现需要被同时标示`required`和`override`修饰符 + +```swift +protocol SomeProtocol { + init() +} + + +class SomeSuperClass { + init() { + //协议定义 + } +} + + +class SomeSubClass: SomeSuperClass, SomeProtocol { + // "required" from SomeProtocol conformance; "override" from SomeSuperClass + required override init() { + // 构造器实现 + } +} +``` + ## 协议类型 @@ -524,6 +580,23 @@ println(game.asPrettyText()) // ○ ○ ▲ ○ ○ ▲ ○ ○ ▲ ▲ ○ ○ ○ ▼ ○ ○ ○ ○ ▼ ○ ○ ▼ ○ ▼ ○ ``` + +## 类专属协议 +你可以在协议的继承列表中,通过添加“class”关键字,限制协议只能适配到类(class)类型。(结构体或枚举不能遵循该协议)。该“class”关键字必须是第一个出现在协议的继承列表中,其后,才是其他继承协议。 + +```swift +protocol SomeClassOnlyProtocol: class, SomeInheritedProtocol { + // class-only protocol definition goes here +} +``` +在以上例子中,协议SomeClassOnlyProtocol只能被类(class)类型适配。如果尝试让结构体或枚举类型适配该协议,则会出现编译错误。 + +>注意 +> +>当协议需求定义的行为,要求(或假设)它的遵循类型必须是引用语义而非值语义时,应该采用类专属协议。关于引用语义,值语义的更多内容,请查看结构体和枚举是值类型类是引用类型 + + + ## 协议合成