Ali
Ali

Reputation: 515

Up casting and down casting confusion in Swift?

class Media {
    var name :String = ""
    init(name:String) {
        self.name = name
    }
}

class Song:Media {}

class Movie:Media{}

let s1 = Song(name :"Fireproof")
var m1 :Media = s1 //upcasting

//var s2 :Song = m1
var s2:Song = m1 as Song //down casting

// var x1 :Movie = m1 as Movie //
  1. On the line var m1: Media = s1 you can set m1 equal to s1 because m1's type is the superclass of s1??

  2. On line var s2: Song = m1 as Song , it is supposedly "down casting", is that because m1: Media and you are "casting" it "as" a Song type in order to match the same type of s2? (If this is true, then why did we set m1 = s1 earlier, when s1 had a different type than m1??)

  3. What's the point of all this up casting and down casting? I've read the apple documentation and managed to confuse myself even more :'(

Upvotes: 4

Views: 7989

Answers (1)

Aaron Brager
Aaron Brager

Reputation: 66302

  1. On the line var m1: Media = s1 you can set m1 equal to s1 because m1's type is the superclass of s1??

Yes. s1 is a Song, which means it is by definition also a Media. Therefore it can be assigned to variables of type Song or Media.

  1. On line var s2: Song = m1 as Song , it is supposedly "down casting", is that because m1: Media and you are "casting" it "as" a Song type in order to match the same type of s2? (If this is true, then why did we set m1 = s1 earlier, when s1 had a different type than m1??)

There is no reason to upcast, then immediately downcast, in actual code. This is just example code showing you things you can do.

BTW, the plain "as" syntax is old Swift - you now need to either use as! if you're sure it will work 100% of the time, or as? if you're not sure. (Google "swift optional casting" for more on this.) Plain old "as" is now only valid for casts that the compiler knows will always work, like from String to NSString.

  1. What's the point of all this up casting and down casting? I've read the apple documentation and managed to confuse myself even more :'(

There's no real point demonstrated in this code. It's often used for interacting with a heterogenous array of types with a common base class. For example, if you have an array of different views, you might want to put them in an array and do something to all of them:

class ViewController : UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        let label = UILabel()
        let button = UIButton()
        let slider = UISlider()

        let views = [label, button, slider] // views is a [UIView]

        for view in views {
            // view is known to be a UIView, even though it is also really a label, button, etc.
            view.translatesAutoresizingMaskIntoConstraints = false
            self.view.addSubview(view)
        }
    }
}

If you're not sure you need to know this, don't worry about it too much for now. Just come back to this when you encounter a problem where you have a bunch of things that are of a similar type but not all the same type.

Upvotes: 5

Related Questions