给定类别Obj
,
class Obj: NSObject {
var x = "x"
}
及其子类Obj1
,如何更改var x
的默认值?
简单地设置一个新值是最有意义的,但是似乎出错了…
class Obj1: Obj {
var x = "y"
}
❗️无法使用存储属性'x'重写
在大多数情况下,通过init
注入这些值是首选的方法。
class Foo
{
var x : String
convenience init()
{
self.init(x: "x") // 'x' by default
}
init(x: String)
{
self.x = x
}
}
class Bar : Foo
{
convenience init()
{
self.init(x: "y") // now 'y' by default
}
init(x: String)
{
super.init(x: x)
}
}
但是,在某些情况下,您想要覆盖计算属性或可能没有完全初始化的内容。
在这种情况下,您可以使用override var
语法:
override var x : String
{
get { return super.x } // get super.x value
set { super.x = newValue } // set super.x value
}
上面的代码不会改变行为,但是演示了允许您这样做的语法。
这个问题已经被标记为答案了,但是还有一种swift模板中安全的方法模式,通过委托给计算属性:
class Foo {
lazy var x : String = self.defaultX
var defaultX:String { return "foo" }
}
class Bar : Foo {
override var defaultX:String { return "bar" }
}
println(Foo().x) // foo
println(Bar().x) // bar
更安全,我指的是Swift对初始化顺序的强制执行,以防止"虚拟"调用到尚未构造的子类(即,让基类调用在子类中实现的虚拟方法,但在子类完成初始化之前)的问题。例如,这在c++中就很危险。
定义init()
方法为:
init () {
super.init()
x = "y"
}
您将希望Obj1
中的任何其他初始化器都像self.init()
一样调用它。Apple文档对指定初始化器和相对于初始化器的继承有很长的讨论。
在swift 3中,我发现chrisco的解决方案不再工作了,但是,如果您在基类中使用private(set)
声明变量,则可以正常工作。
class Parent {
private(set) var name = "Dad"
}
class Child: Parent {
override var name: String { return "Son" }
}