以下编译和运行在运行Swift 4的Xcode 9.2上没有问题:
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类型,只要重写的属性是派生类中的计算只读属性即可。例如,以下代码也将在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的边缘情况,因为Base类的属性是只读的计算属性。因此,如果Bar
的一个实例被保存在Foo
类型的变量中,则无法改变其x
属性,以便在将对象向下转换为Bar
类型的变量时会产生类型错误。