在子类中使用便捷初始化(Swift)
问题描述:
我在Xcode中使用Playground,并且我的对象没有使用它们的名称进行初始化。我觉得这是因为我在我的sublcasses中错误地使用了便利的init,我想知道在子类中使用它们的正确方法是什么。我已阅读其他类似问题,但我认为我的问题与overriding inits
和convenience inits
的方式不同。在子类中使用便捷初始化(Swift)
class Animal
{
var name:String
init(name:String)
{
self.name = name
}
convenience init() { self.init(name: "") }
func speak() { }
}
class Fox: Animal
{
override init(name: String)
{
super.init(name: name)
}
convenience init() { self.init(name: "Fox") }
override func speak()
{
println("Ring")
}
}
class Cat: Animal
{
override init(name: String)
{
super.init(name: name)
}
convenience init() { self.init(name:"Cat") }
override func speak() {
println("Meow")
}
}
class Dog: Animal {
override init(name: String) {
super.init(name: name)
}
convenience init()
{
self.init(name:"Dog")
}
override func speak() {
println("Woof")
}
}
let animals = [ Dog(), Cat(), Fox()]
for animal in animals
{
animal.speak()
}
答
代码中没有错误。 我认为问题在于了解Xcode的操场是如何工作的。 也许你已经按“显示结果”图标,你在像这样看:
但是这是在告诉我们,“模块名称”点“类名”三只动物;前缀__lldb_expr_25(在我的照片中)is not an error,但动态模块名称在操场上没问题。
事实上,你应该看看“助理编辑”:
看到斑点的输出()方法:
这可能是更发音与代码稍作修改:
所以输出:
答
让我根据回答到目前为止,我的理解 -
覆盖inits就像是替换同向同一个超类的init方法。在这里,你可以不添加额外的行为作为一个init方法参数如:
如果你想实现一个init方法到子类class Animal
{
var name:String
init(name:String)
{
self.name = name
}
func speak() { }
}
class Cat: Animal
{
override init(name: String)
{
super.init(name: name)
}
override func speak() {
println("Meow")
}
}
方便inits就像是子类的自定义的init方法手段,但带有一些额外的行为以及超类init方法。如:
class Animal
{
var name:String
init(name:String)
{
self.name = name
}
func speak() { }
}
class Cat: Animal
{
var type: String = "Maine Coons"
convenience init(type:string, name: String)
{
self.type = type
self.init(name: name)
}
override func speak() {
println("Meow")
}
}
我希望它能帮助你。 谢谢
什么问题?你在动物中的动物......对我很有用。你不需要在子类中覆盖init,但是当你重写时,这不是问题。 – GoZoner
speak()无法正常工作。我得到的输出是: – stumped
__lldb_expr_13.Dog __lldb_expr_13.Cat __lldb_expr_13.Fox – stumped