Food
类是RecipeIngredient
的超类。
Food
类引入了一个名为name
的变量和一个指定的初始值设定项init(name: String)
以及一个便捷初始值设定项init()
;
RecipeIngredient
类引入了一个名为quantity
的新变量和一个指定初始值设定项init(name: String, quantity: Int)
以及一个便捷初始值设定项init(name: String)
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 oneMysteryItem = RecipeIngredient()
print("\(oneMysteryItem.name), \(oneMysteryItem.quantity)")//--> [Unnamed], 1
的引用
尽管
RecipeIngredient
提供了init(name: String)
初始化程序作为便利初始化程序,但RecipeIngredient
仍提供了其所有超类指定初始化程序的实现。因此,RecipeIngredient
也会自动继承其所有超类的便利初始化器。
问题1 :子类RecipeIngredient
的便捷初始值设定项和超类Food
的指定初始值设定项具有相同的签名,即。 init(name: String)
。但它们是完全不同的初始化器!所以,我可以说,只要子类中有一个初始化器与超类具有相同的签名,就可以认为子类提供了超类的指定初始化器的含义
问题2 :由于RecipeIngredient
类继承了Food
类的convinece初始值设定项。 let oneMysteryItem = RecipeIngredient()
有效。但print("\(oneMysteryItem.name), \(oneMysteryItem.quantity)")
打印 [未命名],1 ,我真的不明白这1来自何方!发生了什么?固有的便利初始化程序只定义了如何初始化固有值name
,如何定义quantity == 1
?
答案 0 :(得分:1)
问题1:
规则是,如果子类具有任何指定的初始值设定项并且还覆盖其所有超类的DESIGNATED初始值设定项(在子类中将它们标记为指定或方便),则继承超类的CONVENIENCE初始值设定项。
问题2:
RecipeIngredient
已经为其超类的唯一指定初始值设定项(即init(name: String)
)提供了一个重写的初始化程序,因此所有便捷初始化程序都是继承的(即,在这种情况下只是init()
) 。调用RecipeIngredient()
调用init()
便利初始值设定项,后者又调用子类上的init(name: "[Unnamed]")
,子类又调用init(name: "[Unnamed]", quantity: 1)
,即子类的指定初始值设定项
答案 1 :(得分:1)
“init()的继承版本与Food版本完全相同,只是它委托给RecipeIngredient版本的init(name:String)而不是Food版本。”
来源:“The Swift Programming Language(Swift 3.1)”中的Initialization。