Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialJhoan Arango
14,575 PointsDowncasting, “as!”. Someone please, pretend I’m 5 years old and explain downcasting, and why should we use it ?
I understand the basics, but I am not totally clear on it. I can’t move on, if I don’t understand this well. Please try to explain what downcasting is, and why or when should we use it. What is the need for it?
5 Answers
Dustin Morgan
7,551 PointsWell we downcast so that we can access the properties in a subclass when, for instance, we have an array of the super class. We could access anything from its superclass but if we wanted things from its subclass we could not access it without downcasting. The as operator as of Swift 1.2 will actually upcast to the superclass. The as? operator is used if you are not sure it will succeed, you will use this one the most as it is safer for the program when it comes to nil and runtime errors. The as! operator is used only when you are completely sure it will work as it will cause a runtime error but you also wont have to chain optionals after you force unwrap it. Since you learn better visually I would like you to take my code below and put it in a playground and play with it. It will help you understand and give you real time feedback.
class Animal { //Animal gives each one a name
var name: String
init(name: String) {
self.name = name;
}
}
class Bird : Animal { //Bird has properties that Animal and Dog do not but also has property of Animal
var wings = 2
var legs = 2
var featherColor: String
var flightSpeedMPH: Int
init(name: String, flightSpeedMPH: Int, featherColor: String) {
self.featherColor = featherColor
self.flightSpeedMPH = flightSpeedMPH
super.init(name: name)
}
}
class Dog : Animal { //Dog has properties that Animal and Bird do not but also has property of Animal
var legs = 4
var furColor:String
init(name: String, furColor: String) {
self.furColor = furColor
super.init(name: name)
}
}
var animal: [Animal] = [ //Array of our animals
Dog(name: "Fido", furColor: "Black"), //Instance of Dog
Bird(name: "Tweety", flightSpeedMPH: 30, featherColor: "Yellow")] //Instance of Bird
if let myDog = animal[0] as? Dog { //Downcasted Animal class to its subclass Dog
println("My dog has \(myDog.furColor) fur") //Can now access furColor
}
if let myBird = animal[1] as? Bird { //Downcasted Animal class to its subclass Bird
println("My bird can fly at \(myBird.flightSpeedMPH) MPH") //Can now access flightSpeed
}
var dog = animal[0] as! Dog //Forced unwrapped only use when sure it will work
dog.furColor //No need to unwrap
var dog1 = animal[0] as? Dog //Optional unwrapped in case of nil however you must chain optionals later
dog1?.furColor //This is the preffered method if it receives nil it will fail gracefully
dog1!.furColor //This work however if furColor were to be nil it would give a runtime error
var dog2 = dog as Animal //Upcasting dog to animal class
dog2.name //Can only access name, try to access legs of furColor on your own it will fail
Dustin Morgan
7,551 PointsIf you would like to delve deeper than the basics perhaps the Swift docs can tell you what you are looking for and more.
Jhoan Arango
14,575 PointsDustin, before posting the question I did a deep research which included the Swift docs. I may be in need of a break down explanation. Sometimes I need something visual to understand things better. I read all about it, and I understand the basics. But I am not 100% clear. I was, perhaps looking for someone who can kind of break it down for me. Thank you for the advice.
Noel Deles
8,215 PointsDustin's explanation was a lifesaver. But I was still confused with how I could connect my understanding of it (gleaned from Dustin's explanation) to Pasan's explanation in the video. I realized the missing gap was from lack of understanding the AnyObject type. Pasan assumes we would know what being a type of AnyObject entails. To fill the gap I read and reread the Swift documentation on it which can be found here.
Julian Scharf
2,007 PointsThankyou Dustin, you really know your stuff.
tmsmth
10,543 PointsThanks for this explanation, but what happens if we only write :
var dog = animal[0] ?
Could we access furColor ?
Jhoan Arango
14,575 PointsJhoan Arango
14,575 PointsSee, now that’s a great break down visual answer LOL ! thank you very much.
I’ll write down your name for future inquiries LOL !
Thanks once again.
Eduardo Scodino
5,083 PointsEduardo Scodino
5,083 PointsThank you, your explanation has helped a lot.