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 trial

iOS

Jhoan Arango
Jhoan Arango
14,575 Points

Downcasting, “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
Dustin Morgan
7,551 Points

Well 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
Jhoan Arango
Jhoan Arango
14,575 Points

See, 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.

Thank you, your explanation has helped a lot.

Dustin Morgan
Dustin Morgan
7,551 Points

If 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
Jhoan Arango
14,575 Points

Dustin, 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
Noel Deles
8,215 Points

Dustin'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
Julian Scharf
2,007 Points

Thankyou Dustin, you really know your stuff.

Thanks for this explanation, but what happens if we only write :

var dog = animal[0] ?

Could we access furColor ?