Inherited convenience initializer - 为什么它有效?
Inherited convenience initializer - why does this work?
我有下面的例子和一个问题:
我知道在某些情况下初始化程序是继承的。
class Food{
var name: String
init(name: String) {
self.name = name
}
convenience init() {
self.init(name: "[unnamed]")
}
}
class RecipeIngredient: Food {
var quantity: Int
init(name: String, quantity: Int){
self.quantity = quantity
super.init(name: name)
}
override convenience init(name: String){
self.init(name: name, quantity: 1)
}
}
let mystery = RecipeIngredient() // Why does this work?
我原以为没有任何参数的初始化不起作用,因为便利初始化器仅在基 class 中声明并且没有设置数量 属性.
显然它无论如何都有效。但为什么?当我在没有任何参数的情况下调用(至少在子 class 不存在的)初始化程序时,后台会发生什么?
子 class 中定义了初始化器,并且从超级 class 中定义了初始化器(当然除非它们中的任何一个在子 class 中被覆盖)。所以在这种情况下 RecipeIngredient
有 3 个初始化
来自RecipeIngredient
init(name: String, quantity: Int){
self.quantity = quantity
super.init(name: name)
}
override convenience init(name: String){
self.init(name: name, quantity: 1)
}
还有一个来自 Food
convenience init() {
self.init(name: "[unnamed]")
}
现在便利 init 必须直接或通过另一个便利 init 调用默认 init,所以这里的调用链变成了
Food.init() -> RecipeIngredient.init(name:) -> RecipeIngredient(name:quantity) -> Food.init(name:)
这可以通过将 print(#function)
添加到每个 init 来很容易地看到,它给出
的输出
let mystery = RecipeIngredient()
init()
init(name:)
init(name:quantity:)
init(name:)
我有下面的例子和一个问题:
我知道在某些情况下初始化程序是继承的。
class Food{
var name: String
init(name: String) {
self.name = name
}
convenience init() {
self.init(name: "[unnamed]")
}
}
class RecipeIngredient: Food {
var quantity: Int
init(name: String, quantity: Int){
self.quantity = quantity
super.init(name: name)
}
override convenience init(name: String){
self.init(name: name, quantity: 1)
}
}
let mystery = RecipeIngredient() // Why does this work?
我原以为没有任何参数的初始化不起作用,因为便利初始化器仅在基 class 中声明并且没有设置数量 属性.
显然它无论如何都有效。但为什么?当我在没有任何参数的情况下调用(至少在子 class 不存在的)初始化程序时,后台会发生什么?
子 class 中定义了初始化器,并且从超级 class 中定义了初始化器(当然除非它们中的任何一个在子 class 中被覆盖)。所以在这种情况下 RecipeIngredient
来自RecipeIngredient
init(name: String, quantity: Int){
self.quantity = quantity
super.init(name: name)
}
override convenience init(name: String){
self.init(name: name, quantity: 1)
}
还有一个来自 Food
convenience init() {
self.init(name: "[unnamed]")
}
现在便利 init 必须直接或通过另一个便利 init 调用默认 init,所以这里的调用链变成了
Food.init() -> RecipeIngredient.init(name:) -> RecipeIngredient(name:quantity) -> Food.init(name:)
这可以通过将 print(#function)
添加到每个 init 来很容易地看到,它给出
let mystery = RecipeIngredient()
init()
init(name:)
init(name:quantity:)
init(name:)