Merge pull request #442 from chenmingbiao/develop

构造过程,重写与重载问题修改
This commit is contained in:
梁杰
2015-08-05 10:49:36 +08:00

View File

@ -149,7 +149,7 @@ let veryGreen = Color(0.0, 1.0, 0.0)
### 不带外部名的构造器参数 ### 不带外部名的构造器参数
如果你不希望为构造器的某个参数提供外部名字,你可以使用下划线(_)来显示描述它的外部名,以此覆盖上面所说的默认行为。 如果你不希望为构造器的某个参数提供外部名字,你可以使用下划线(_)来显示描述它的外部名,以此重写上面所说的默认行为。
下面是之前`Celsius`例子的扩展,跟之前相比添加了一个带有`Double`类型参数名为`celsius`的构造器,其外部名用`_`代替。 下面是之前`Celsius`例子的扩展,跟之前相比添加了一个带有`Double`类型参数名为`celsius`的构造器,其外部名用`_`代替。
@ -472,21 +472,21 @@ Swift 编译器将执行 4 种有效的安全检查,以确保两段式构造
最终,一旦子类的指定构造器完成调用,最开始被调用的便利构造器可以执行更多的定制操作。 最终,一旦子类的指定构造器完成调用,最开始被调用的便利构造器可以执行更多的定制操作。
<a name="initializer_inheritance_and_overriding"></a> <a name="initializer_inheritance_and_overriding"></a>
### 构造器的继承和重 ### 构造器的继承和重
跟 Objective-C 中的子类不同Swift 中的子类不会默认继承父类的构造器。Swift 的这种机制可以防止一个父类的简单构造器被一个更专业的子类继承,并被错误的用来创建子类的实例。 跟 Objective-C 中的子类不同Swift 中的子类不会默认继承父类的构造器。Swift 的这种机制可以防止一个父类的简单构造器被一个更专业的子类继承,并被错误的用来创建子类的实例。
>注意: >注意:
父类的构造器仅在确定和安全的情况下被继承。具体内容请参考后续章节[自动构造器的继承](#automatic_initializer_inheritance)。 父类的构造器仅在确定和安全的情况下被继承。具体内容请参考后续章节[自动构造器的继承](#automatic_initializer_inheritance)。
假如你希望自定义的子类中能实现一个或多个跟父类相同的构造器,也许是为了完成一些定制的构造过程,你可以在你定制的子类中提供和重与父类相同的构造器。 假如你希望自定义的子类中能实现一个或多个跟父类相同的构造器,也许是为了完成一些定制的构造过程,你可以在你定制的子类中提供和重与父类相同的构造器。
当你写一个父类中带有指定构造器的子类构造器时,你需要重这个指定的构造器。因此,你必须在定义子类构造器时带上`override`修饰符。即使你重系统提供的默认构造器也需要带上`override`修饰符,具体内容请参考[默认构造器](#default_initializers)。 当你写一个父类中带有指定构造器的子类构造器时,你需要重这个指定的构造器。因此,你必须在定义子类构造器时带上`override`修饰符。即使你重系统提供的默认构造器也需要带上`override`修饰符,具体内容请参考[默认构造器](#default_initializers)。
无论是重属性,方法或者是下标脚本,只要含有`override`修饰符就会去检查父类是否有相匹配的重指定构造器和验证重构造器参数。 无论是重属性,方法或者是下标脚本,只要含有`override`修饰符就会去检查父类是否有相匹配的重指定构造器和验证重构造器参数。
>注意: >注意:
当你重一个父类指定构造器时,你需要写`override`修饰符,甚至你的子类构造器继承的是父类的便利构造器。 当你重一个父类指定构造器时,你需要写`override`修饰符,甚至你的子类构造器继承的是父类的便利构造器。
相反地,如果你写了一个和父类便利构造器相匹配的子类构造器,子类都不能直接调用父类的便利构造器,每个规则都在上文[构造器链](#initialization_chain)有所描述。 相反地,如果你写了一个和父类便利构造器相匹配的子类构造器,子类都不能直接调用父类的便利构造器,每个规则都在上文[构造器链](#initialization_chain)有所描述。
@ -538,7 +538,7 @@ print("Bicycle: \(bicycle.description)")
<a name="automatic_initializer_inheritance"></a> <a name="automatic_initializer_inheritance"></a>
### 自动构造器的继承 ### 自动构造器的继承
如上所述,子类不会默认继承父类的构造器。但是如果特定条件可以满足,父类构造器是可以被自动继承的。在实践中,这意味着对于许多常见场景你不必重父类的构造器,并且在尽可能安全的情况下以最小的代价来继承父类的构造器。 如上所述,子类不会默认继承父类的构造器。但是如果特定条件可以满足,父类构造器是可以被自动继承的。在实践中,这意味着对于许多常见场景你不必重父类的构造器,并且在尽可能安全的情况下以最小的代价来继承父类的构造器。
假设要为子类中引入的任意新属性提供默认值请遵守以下2个规则 假设要为子类中引入的任意新属性提供默认值请遵守以下2个规则
@ -616,7 +616,7 @@ class RecipeIngredient: Food {
`RecipeIngredient`也定义了一个便利构造器`init(name: String)`,它只通过`name`来创建`RecipeIngredient`的实例。这个便利构造器假设任意`RecipeIngredient`实例的`quantity`为1所以不需要显示指明数量即可创建出实例。这个便利构造器的定义可以让创建实例更加方便和快捷并且避免了使用重复的代码来创建多个`quantity`为 1 的`RecipeIngredient`实例。这个便利构造器只是简单的将任务代理给了同一类里提供的指定构造器。 `RecipeIngredient`也定义了一个便利构造器`init(name: String)`,它只通过`name`来创建`RecipeIngredient`的实例。这个便利构造器假设任意`RecipeIngredient`实例的`quantity`为1所以不需要显示指明数量即可创建出实例。这个便利构造器的定义可以让创建实例更加方便和快捷并且避免了使用重复的代码来创建多个`quantity`为 1 的`RecipeIngredient`实例。这个便利构造器只是简单的将任务代理给了同一类里提供的指定构造器。
注意,`RecipeIngredient`的便利构造器`init(name: String)`使用了跟`Food`中指定构造器`init(name: String)`相同的参数。因为这个便利构造器重写要父类的指定构造器`init(name: String)`,必须在前面使用使用`override`标识(参见[构造器的继承和重](#initializer_inheritance_and_overriding))。 注意,`RecipeIngredient`的便利构造器`init(name: String)`使用了跟`Food`中指定构造器`init(name: String)`相同的参数。因为这个便利构造器重写要父类的指定构造器`init(name: String)`,必须在前面使用使用`override`标识(参见[构造器的继承和重](#initializer_inheritance_and_overriding))。
在这个例子中,`RecipeIngredient`的父类是`Food`,它有一个便利构造器`init()`。这个构造器因此也被`RecipeIngredient`继承。这个继承的`init()`函数版本跟`Food`提供的版本是一样的,除了它是将任务代理给`RecipeIngredient`版本的`init(name: String)`而不是`Food`提供的版本。 在这个例子中,`RecipeIngredient`的父类是`Food`,它有一个便利构造器`init()`。这个构造器因此也被`RecipeIngredient`继承。这个继承的`init()`函数版本跟`Food`提供的版本是一样的,除了它是将任务代理给`RecipeIngredient`版本的`init(name: String)`而不是`Food`提供的版本。