Initialization always throws me for a loop in every language, and Swift is no different. Whoever wants to pick this apart, please feel free.
Silver Challenge
This necessitated the need to remove the required
attribute from the Monster
and Zombie
initializers, and modify Zombie
's initializer to be a convenient one that calls its designated initializer, which in turn calls its superclass’s (Monster
) initializer. For some reason the compiler was throwing an error for this new initializer, and I’m a little confused–it said I was overriding the superclass’s initializer, but aren’t we doing that in the other convenience initializer? Is it because initialization call is the same, thats why you need to specify that you’re overriding? Any help answering this would clear up a lot of issues in my head.
/// Monster.swift
init(town: Town?, monsterName: String) {
self.town = town
name = monsterName
}
I specified limp
and fallingApart
in the initialization call because I was getting errors trying to set them before initialization.
/// Zombie.swift
convenience override init(town: Town?, monsterName: String) {
self.init(limp: false, fallingApart: false, town: town, monsterName: monsterName)
}
Gold Challenge
To fix the issue we are experiencing, you have to use a guard
statement and change the initializer to denote that it is failable (adding a ?
):
init?(town: Town?, monsterName: String) {
guard monsterName.characters.count > 0 else {
return nil
}
self.town = town
name = monsterName
}
Now we need to clean up all of Zombie
's initializers (just adding ?
s everywhere we can):
/// Zombie.swift
init?(limp: Bool, fallingApart: Bool, town: Town?, monsterName: String) {
walksWithLimp = limp
isFallingApart = fallingApart
super.init(town: town, monsterName: monsterName)
}
convenience init?(limp: Bool, fallingApart: Bool) {
self.init(limp: limp, fallingApart: fallingApart, town: nil, monsterName: "Fred")
if walksWithLimp {
print("This zombie has a bad knee.")
}
}
convenience override init?(town: Town?, monsterName: String) {
self.init(limp: false, fallingApart: false, town: town, monsterName: monsterName)
}
And to test the code:
/// main.swift
var failableMonster = Monster(town: myTown, monsterName: "")
print(failableMonster?.name) // -> prints nil