Swift documentation says here in regards to the initializer delegation:
A designated initializer must delegate up to a superclass initializer before assigning a value to an inherited property. If it doesn’t, the new value the designated initializer assigns will be overwritten by the superclass as part of its own initialization.
Let's say in the following example:
class Shape {
var color: String
init(color: String) {
self.color = color
}
}
class Circle: Shape {
let pi = 3.14
var r: Double
init(r: Double, color: String) {
self.r = r
super.init(color: color)
}
func area() -> Double {
return pi * r * r
}
}
what does it mean to "delegate up to a superclass initializer before assigning a value to an inherited property"? My assumption is that the "inherited property" means none of the properties newly introduced by the subclass.
Isn't the very act of delegating up to a superclass initializer, super.init(color: color)
, assigning a value to inherited property? How do I assign to the inherited properties first and then delegate up to a superclass initializer? What would be an example of the new value being overwritten by the superclass initializer?
Your example doesn't actually involve the modifying an inherited property in a subclass initialiser. An inherited property is a property declared by the superclass (such as color
in your example).
That piece of documentation says that if you want to override the behaviour of the super initialiser and modify the value of an inherited property in the subclass init, you first need to call super.init
and only then can you modify the value. This is because all values declared by the superclass will be initialised in super.init
.
Actually, the compiler doesn't even allow you to access values declared in the superclass before calling super.init
to avoid the errors mentioned by the documentation.
Check the below example, where the superclass assigns a constant value to id
, regardless of what the input value to the init
was, while the subclass uses the input value and hence overrides the value assigned in the superclass.
class Super {
var id: Int
init(id: Int) {
self.id = 0
}
}
class Sub: Super {
let prop: String
init(id: Int, prop: String) {
self.prop = prop
// The next line would actually result in the error: 'self' used in property access 'id' before 'super.init' call
//self.id = id
super.init(id: id)
self.id = id // this is where you can override a property declared by the superclass
}
}
Sub(id: 2, prop: "") // id is correctly initialised to 2