自动初始化程序继承的条件是初始化程序的签名

时间:2016-07-04 20:43:55

标签: swift inheritance initialization

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

来自office document

的引用
  

尽管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

2 个答案:

答案 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