Leave a rating/review
Notes: 39. Challenge: Inheritance
Update Notes: This course was originally recorded in 2019. It has been reviewed and all content and materials updated as of October 2021.
I’ve got an inheritance challenge for you! Again, everything you need is in the playground for this part of the course. Pause the video, and do your best to work through the exercises. Then, come back to see how I did things. Have fun!
First! Create a class named Animal that has… a function named speak() that does nothing. That’s pretty straightforward.
class Animal {
func speak() { }
}
That class doesn’t need an initializer, because it doesn’t have any stored properties. Just the one method. Next part - Create two Animal subclasses… Number one, a WildAnimal that… has an isPoisonous property, that is a Bool
class WildAnimal: Animal {
let isPoisonous: Bool
}
This one does need an initializer to set that isPoisonous property!
init(isPoisonous: Bool) {
self.isPoisonous = isPoisonous
}
}
Subclass number 2 should be a Pet class that has a stored property named name, that is a String
class Pet: Animal {
let name: String
}
That one also needs an initializer to see its property.
init(name: String) {
self.name = name
}
Pet also needs a play() method that prints out a message.
func play() {
print("Playtime! ... now naptime 💤")
}
You could have done whatever you wanted with the parameters for that, but I just kept mine simple. And the final thing for pet, it should override speak() and print out a message
override func speak() {
print("Hi I'm \(name)! I am cute. Pet me!")
}
I went ahead and used the name property in that message. Alright the last part of challenge 1! This was more open ended.
Create one subclass of your choice of WildAnimal or Pet. It should do at least one of the following:
-
override
speak() -
override
play() - Add a new computed property
- Add a new method
I’ll make a Cat class that says what all cats say.
class Cat: Pet {
override func speak() {
print("I can has Cheezeburger?")
}
}
I can has cheezburger. Note the override keyword in front of that method!
On to challenge two! Create at least one instance of each class from the first challenge.
let animal = Animal()
let babyAragog = WildAnimal(isPoisonous: true)
let babySmaug = WildAnimal(isPoisonous: false)
let hamtaro = Pet(name: "Hamtaro")
let ozma = Cat(name: "Ozma")
I made two wild animals so one would be poisonous and one not. Next, Create an array that contains all of the instances.
let animals = [animal, babyAragog, babySmaug, hamtaro, ozma]
Swift is helping me out there, because it can figure out what the common parent class is for all of those instances! Now for the potentially longest part.
Write a function that takes an Animal and does something different depending on what subclass it is. This part is particularly vague, so you could have made it as complicated or simple as you liked.
I’ll write a function that prints out the pitch to give your family when you bring home some kind of animal and want to keep it.
func printElevatorPitch(forAnimal animal: Animal) {
}
The challenge suggested conditional downcasting, so, I’ll try that first with if let, checking for WildAnimals
if let animal = animal as? WildAnimal {
}
If it is a wild animal, I’ll print out something different depending on if it’s poisonous or not.
print(animal.isPoisonous ? "It's only a little poisonous!" : "It's not even poisonous!")
return
}
I just used a ternary operator for that, but you could have use if or even a switch statement! Note that I also used return at the end to make sure the function stops running after the message is printed. Next, I’ll check for Pets.
if let pet = animal as? Pet {
And inside there, since I have a Cat class that derives from Pet, I’ll switch things up and use a switch statement to pick the right printed message.
switch pet {
}
When you use a switch statement, and you want to see if you can downcast, you leave off the question mark.
case let cat as Cat:
print("It's a kitty named \(cat.name)! I've always wanted a kitty.")
cat.speak()
return
And then, because Pet only has the one subclass, I’ll use a default case to catch regular old Pets.
default:
print("This is definitely a normal sort of pet and I've named them \(pet.name).")
pet.speak()
pet.play()
return
}
I could leave it at that, but I’ll add one more print statement if none of those casts succeed. At that point, I could assume it’s of type Animal.
print("It's Animal! You know, the Muppet?")
}
The very last bit of this challenge was to call the function with each of your instances. I’ll do that with forEach!
animals.forEach(printElevatorPitch(forAnimal:))
And there’s all of the possible messages in the console!