What is Type Casting?
Type casting is a way to check the type of an instance, or to treat that instance as a different superclass or subclass from somewhere else in its own class hierarchy.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
class Subjects { var physics: String init(physics: String) { self.physics = physics } } class Chemistry: Subjects { var equations: String init(physics: String, equations: String) { self.equations = equations super.init(physics: physics) } } class Maths: Subjects { var formulae: String init(physics: String, formulae: String) { self.formulae = formulae super.init(physics: physics) } } let sa = [ Chemistry(physics: "solid physics", equations: "Hertz"), Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz")] let samplechem = Chemistry(physics: "solid physics", equations: "Hertz") print("Instance physics is: \(samplechem.physics)") print("Instance equation is: \(samplechem.equations)") let samplemaths = Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz") print("Instance physics is: \(samplemaths.physics)") print("Instance formulae is: \(samplemaths.formulae)") |
Checking Type
Use the type check operator (is) to check whether an instance is of a certain subclass type. The type check operator returns true if the instance is of that subclass type and false if it is not.
1 2 3 4 5 6 7 8 9 10 11 |
var chemCount = 0 var mathsCount = 0 for item in sa { if item is Chemistry { ++chemCount } else if item is Maths { ++mathsCount } } print("Subjects in chemistry contains \(chemCount) topics and maths contains \(mathsCount) topics") |
Downcasting
A constant or variable of a certain class type may actually refer to an instance of a subclass behind the scenes. Where you believe this is the case, you can try to downcast to the subclass type with a type cast operator (as? or as!).’
- Conditional down casting (as?): as?’ returns an optional value of the type you are trying to downcast to.
- Forced down casting (as!): ‘as!’ attempts the downcast and force-unwraps the result as a single compound action.
1 2 3 4 5 6 7 8 9 10 |
var chemCount = 0 var mathsCount = 0 for item in sa { if let print = item as? Chemistry { print("Chemistry topics are: '\(print.physics)', \(print.equations)") } else if let example = item as? Maths { print("Maths topics are: '\(example.physics)', \(example.formulae)") } } |
Type Casting: Any and Any Object
Swift provides two special types for working with nonspecific types:
- Any can represent an instance of any type at all, including function types.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
var chemCount = 0 var mathsCount = 0 for item in sa { if let print = item as? Chemistry { print("Chemistry topics are: '\(print.physics)', \(print.equations)") } else if let example = item as? Maths { print("Maths topics are: '\(example.physics)', \(example.formulae)") } } var exampleany = [Any]() exampleany.append(12) exampleany.append(3.14159) exampleany.append("Example for Any") exampleany.append(Chemistry(physics: "solid physics", equations: "Hertz")) for print in exampleany { switch print { case let someInt as Int: print("Integer value is \(someInt)") case let someDouble as Double where someDouble > 0: print("Pi value is \(someDouble)") case let someString as String: print("\(someString)") case let phy as Chemistry: print("Topics '\(phy.physics)', \(phy.equations)") default: print("None") } } |
- AnyObject can represent an instance of any class type.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
class Subjects { var physics: String init(physics: String) { self.physics = physics } } class Chemistry: Subjects { var equations: String init(physics: String, equations: String) { self.equations = equations super.init(physics: physics) } } class Maths: Subjects { var formulae: String init(physics: String, formulae: String) { self.formulae = formulae super.init(physics: physics) } } let saprint: [AnyObject] = [Chemistry(physics: "solid physics", equations: "Hertz"), Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz"), Chemistry(physics: "Thermo physics", equations: "Decibels"), Maths(physics: "Astro Physics", formulae: "MegaHertz"), Maths(physics: "Differential Equations", formulae: "Cosine Series")] let samplechem = Chemistry(physics: "solid physics", equations: "Hertz") print("Instance physics is: \(samplechem.physics)") print("Instance equation is: \(samplechem.equations)") let samplemaths = Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz") print("Instance physics is: \(samplemaths.physics)") print("Instance formulae is: \(samplemaths.formulae)") var chemCount = 0 var mathsCount = 0 for item in saprint { if let print = item as? Chemistry { print("Chemistry topics are: '\(print.physics)', \(print.equations)") } else if let example = item as? Maths { print("Maths topics are: '\(example.physics)', \(example.formulae)") } } var exampleany = [Any]() exampleany.append(12) exampleany.append(3.14159) exampleany.append("Example for AnyObject") exampleany.append(Chemistry(physics: "solid physics", equations: "Hertz")) for print in exampleany { switch print { case let someInt as Int: print("Integer value is \(someInt)") case let someDouble as Double where someDouble > 0: print("Pi value is \(someDouble)") case let someString as String: print("\(someString)") case let phy as Chemistry: print("Topics '\(phy.physics)', \(phy.equations)") default: print("None") } } |