Reputation: 22633
Given class Obj
,
class Obj: NSObject {
var x = "x"
}
and its subclass, Obj1
, how do you change the default value of var x
?
Simply setting a new value would make the most sense, but it seems to error out...
class Obj1: Obj {
var x = "y"
}
❗️ Cannot override with a stored property 'x'
Upvotes: 11
Views: 6332
Reputation: 468
In swift 3 I've found that chrisco's solution doesn't work anymore,
But it works if you declare the variable in the base class with private(set)
.
class Parent {
private(set) var name = "Dad"
}
class Child: Parent {
override var name: String { return "Son" }
}
Upvotes: 1
Reputation: 9039
This question has been marked answered, but there is also the safe-in-Swift template method pattern by way of delegation to a computed property:
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
By safer, I am referring to Swift's enforcement of the initialization sequence that prevents problems with "virtual" calls into a not-yet constructed sub class (ie, having a base class call a virtual method that is implemented in a sub class, but before that subclass has finished initializing). This was a danger in C++, for example.
Upvotes: 6
Reputation: 12858
In most cases, injecting these values via init
is the preferred way.
For example:
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)
}
}
However, there are some cases where you want to override a computed property or perhaps something that is not exactly initialized.
In this case, you can use the override var
syntax:
override var x : String
{
get { return super.x } // get super.x value
set { super.x = newValue } // set super.x value
}
The above code does not change the behavior, but illustrates the syntax that would allow you to do so.
Upvotes: 9
Reputation: 70185
Define an init()
method as:
init () {
super.init()
x = "y"
}
You'll want any other initializers in Obj1
to invoke this as self.init()
. The Apple documentation has a long discussion on designated initializers and inheritance vis-a-vis initializers.
Upvotes: 3