用 returns 非可选值覆盖 属性 一个可选值 returns 一个可选值
Overriding a computed property that returns an Optional value with one that returns a non-Optional
以下在我的 Xcode 9.2 运行 Swift 4:
上编译和运行没有问题
class ParentWithComputedOptional {
var computedOptional: Int? { return nil }
}
class ChildThatUnwraps: ParentWithComputedOptional {
override var computedOptional: Int { return 10 }
}
请注意,在父项中,computedOptional
是一个 Int?
,但在子项中它被覆盖为 Int
。此外,必须为要编译的代码指定 override
关键字。这已经在 Playground 和一个合适的项目上进行了测试。
这是预期的行为吗?如果是,Apple 的文档中是否有针对这种情况的相关页面?
这种重写的特殊情况似乎没有在官方语言指南中的任何地方记录,但在 Swift 的 changelog 4.0 版本中有所提及(查找 SR-1529 ).
这个主题需要一些额外的信息:
实际上,这种行为不仅限于可选类型,也适用于其他 covariant 类型,只要被覆盖的 属性 是派生 class。
例如,以下代码也可以在 Swift 4.1.
中编译
class Animal {}
class Koala: Animal {}
class Foo {
var x: Animal { return Animal() }
}
class Bar: Foo {
override var x: Koala { return Koala() }
}
这是一个不违反 Liskov substitution principle 的边缘情况,因为基础 class' 属性 是只读计算的。因此,如果 Bar
的一个实例被保存在类型 Foo
的变量中,就没有办法改变它的 x
属性 以便它将对象向下转换为 Bar
.
类型的变量时会产生类型错误
以下在我的 Xcode 9.2 运行 Swift 4:
上编译和运行没有问题class ParentWithComputedOptional {
var computedOptional: Int? { return nil }
}
class ChildThatUnwraps: ParentWithComputedOptional {
override var computedOptional: Int { return 10 }
}
请注意,在父项中,computedOptional
是一个 Int?
,但在子项中它被覆盖为 Int
。此外,必须为要编译的代码指定 override
关键字。这已经在 Playground 和一个合适的项目上进行了测试。
这是预期的行为吗?如果是,Apple 的文档中是否有针对这种情况的相关页面?
这种重写的特殊情况似乎没有在官方语言指南中的任何地方记录,但在 Swift 的 changelog 4.0 版本中有所提及(查找 SR-1529 ).
这个主题需要一些额外的信息:
实际上,这种行为不仅限于可选类型,也适用于其他 covariant 类型,只要被覆盖的 属性 是派生 class。 例如,以下代码也可以在 Swift 4.1.
中编译class Animal {}
class Koala: Animal {}
class Foo {
var x: Animal { return Animal() }
}
class Bar: Foo {
override var x: Koala { return Koala() }
}
这是一个不违反 Liskov substitution principle 的边缘情况,因为基础 class' 属性 是只读计算的。因此,如果 Bar
的一个实例被保存在类型 Foo
的变量中,就没有办法改变它的 x
属性 以便它将对象向下转换为 Bar
.