Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change variable to subclass in Swift

In Swift if I have a base class and two classes that inherit from it that have their own properties. If I assign a variable to the base class then later change it to the subclass, I can't access said properties. Here is a really dumb example. It's what I could think of in a pinch. http://swiftstub.com/927736954/?v=gm

class Animal {
    let alive = true
}

class Human:Animal {
    let socks:Int = 5
}

class Dog:Animal {
    let collar = "fun"
}

var a:Animal!

var letter = "h"

switch letter {
    case "d":
        a = Dog()
    case "h":
        a = Human()
    default:
        a = Animal()
}

print(a is Human) // TRUE
print(a.socks) // :28:7: error: 'Animal' does not have a member named 'socks'

How can I initially set a variable as a base class and turn it into it's subclass and access properties of said subclass?

like image 475
Johnston Avatar asked Dec 25 '22 13:12

Johnston


2 Answers

You need to downcast your variable. So print(a.socks) should be replaced with

if a is Human {
  print((a as! Human).socks)
}

or with additional variable

if let b = a as? Human {
  print(b.socks)
}

upd:

You can also achieve this with guard:

guard let a = a as? Human
  else { return }
print(a.socks)
like image 146
rkyr Avatar answered Dec 28 '22 06:12

rkyr


This is a pretty common scenario in Object Oriented Programming.

Answer by R.K. is totally correct. I just want to add here another way to achieve the same result.

You can use a switch to find the correct type of your variable and perform a downcast:

var some : Animal?

some = Human() // or some = Dog() or some = Animal()

switch some {
case let human as Human: print("It's a human with \(human.socks) socks")
case let dog as Dog: print("It's a Dog! The collar says: \(dog.collar)")
default: print("It's some unknown kind of animal")
}

Hope this helps.

like image 43
Luca Angeletti Avatar answered Dec 28 '22 05:12

Luca Angeletti