Swift - Type Casting



What is Type Casting in Swift?

Type casting is a special feature in Swift, which is used to check the type of the instance or change the type of instance from a class, structure or enumeration to another class, structure or enumeration. It is important because it allows run-time type checking and safe downcasting of instances to subclass types.

Swift supports two operators: is and as. The ‘is’ operator is used to check the type of a value and 'as' is used to cast the type value to a different type. Type casting also checks whether the instance type follows a particular protocol conformance standard.

Swift supports two types of type casting −

  • Upcasting
  • Downcasting

Upcasting in Swift

The process of casting an instance of subclass into its base class type is known as upcasting. Or we can say that upcasting is a process in which we treat the instance of a derived class as an instance of its base class. With the help of upcasting, we can only call the methods and properties of the superclass. After upcasting we are not allowed to directly call the methods or properties of the subclass, if you try to do you will get an error.

In Swift, upcasting is implicit means we don't require any special syntax for upcasting, we can directly cast the instance of subclass as the instance of superclass. It is safe to use directly because the instance of the subclass is always treated as the instance of the superclass. Upcasting is commonly used while we are working with polymorphic code or when we want to treat an instance of a different type as the instance of its common base type.

Example

Swift program for upcasting the instance of the subclass as the instance of the superclass.

// Base class
class Shape {
   func display(){
      print("Ball is in the shape of sphere")
   }
}

// Sub class
class Rectangle: Shape {
   func show(){
      print("Rectangle is the most commonly used shape")
   }
}

// Creating an instance of the Rectangle class
let rect = Rectangle()

// Upcasting the instance of the rectangle class as the instance of the Shape class
let obj : Shape = rect

// Accessing the method of superclass
obj.display()

// Now we are not able to directly access the method or properties of the sub-class
// If we do we will get an error
// obj.show()

Output

It will produce the following output −

Ball is in the shape of sphere

Downcasting in Swift

The process of casting an instance of a superclass type into a subclass type is known s downcasting. Or we can say that downcasting is a process in which we treat the instance of the base class as an instance of the derived class. It is not necessary that downcasting is always successful, it can be a failure. Swift supports two types of downcasting −

  • Conditional Downcasting(as?)
  • Forced Downcasting(as!)

Let's discuss both of them in detail

Conditional Downcasting(as?)

The conditional downcasting (as?) operator is used to downcast an instance of the superclass type to a specific subclass type. This operator will return an optional containing the instance of the subclass when the downcast is successful. When the downcast is unsuccessful, then this operator will return nil. This operator is generally used when we are not sure whether the downcast will be a success or not.

Syntax

Following is the syntax of the conditional downcasting operator(as?) −

if let constName = instance as? Type {
   // Statement that will execute when downcast is successful
} else {
   // Statement that will execute when downcast is unsuccessful
}

Example

Swift program to demonstrate the use of conditional downcasting operator(as?).

// Base Class
class ProgrammingLanguage {
   func show() {
      print("Welcome to the great world of learning")
   }
}

// Subclass
class Swift: ProgrammingLanguage {
   func display() {
      print("Welcome to Swift tutorial")
   }
}
let obj: ProgrammingLanguage = Swift()

// Here the conditional downcasting will be successful
if let result1 = obj as? Swift {
   print("Downcast is successful!")
    
   // Accessing subclass method
   result1.display() 
} else {
   print("Downcast is unsuccessful")
}

// Here the conditional downcasting will be unsuccessful
let newObj: ProgrammingLanguage = ProgrammingLanguage()

if let result2 = newObj as? Swift {
   print("\nDowncast is successful!")
   result2.display()
} else {
   print("Downcast is unsuccessful")
}
Output

It will produce the following output −

Downcast is successful!
Welcome to Swift tutorial
Downcast is unsuccessful

Forced Downcasting(as!)

The forced downcasting (as!) operator is used to forcefully downcast an instance to a given subclass type. This operator will return an instance of the subclass. If the downcast is unsuccessful, then it will give a runtime error. This operator is generally used when we are sure that downcast will be a success.

Syntax

Following is the syntax for forced downcasting(as!) −

let constantName = instance as! type

Example

Swift program to demonstrate the use of forced downcasting operator(as!).

// Base Class
class ProgrammingLanguage {
   func show() {
      print("Welcome to the great world of learning")
   }
}

// Subclass
class Swift: ProgrammingLanguage {
   func display() {
      print("Welcome to Swift tutorial")
   }
}
let obj: ProgrammingLanguage = Swift()

// Here the forced downcasting will be successful
let res1 = obj as! Swift

// Accessing the method of Swift class
res1.display()

// Here the forced downcasting will be successful so we will get an error
/*let newobj: ProgrammingLanguage = ProgrammingLanguage()
let res2 = newobj as! Swift
res2.display()*/
Output

It will produce the following output −

Welcome to Swift tutorial

Type Checking

In Swift, type-checking is used to determine whether the given instance belongs to the specified subclass or not. We can perform type-checking using is operator. If the instance belongs to the specified class, then this operator will return true. If the instance does not belong to the specified class, then this operator will return false.

Syntax

Following is the syntax for type checking −

let constantName = instance as! type

Example

Swift program to demonstrate how to check the type of instance.

// Base Class
class ProgrammingLanguage {
   func show() {
      print("Welcome to the great world of learning")
   }
}

// Subclass
class Swift: ProgrammingLanguage {
   func display() {
      print("Welcome to Swift tutorial")
   }
}

let obj: ProgrammingLanguage = Swift()

// Type Checking
if obj is Swift{
   print("obj is the instance of Swift class")
} else {
   print("No obj is not the instance of Swift class")
}

Output

It will produce the following output −

obj is the instance of Swift class

Typecasting Any and AnyObject

Swift supports two special types that are used for working with values of unknown type and instance of class and these types are:

  • Any − The Any is used to represent an instance that belongs to any type including function types. It also includes optional types.

  • AnyObject − The AnuObject is used to represent an instance of any class type.

We can perform both type casting and type checking on Any and AnyObject.

Example

Swift program to demonstrate type casting for Any.

// Type Casting for Any
var myValue: Any = 22

// Type Checking using is operator 
if myValue is Int {
   print("Yes myValue is of Int type!")
} else {
   print("No myValue is not of Int type!")
}

// Type Casting using as? operator
if let res = myValue as? Int {
   print("Successfully casted to Int: \(res)")
} else {
   print("Could not be able to cast into Int")
}

Output

It will produce the following output −

Yes myValue is of Int type!
Successfully casted to Int: 22

Example

Swift program to demonstrate type casting for AnyObject.

// Base Class
class ProgrammingLanguage {
   func show() {
      print("Welcome to the great world of learning")
   }
}

// Subclass
class Swift: ProgrammingLanguage {
   func display() {
      print("Welcome to Swift tutorial")
   }
}

// Instance of any object type
let obj: AnyObject = Swift()

// Type Checking using is operator
if obj is Swift {
   print("Yes it is the instance of Swift")
} else {
   print("No it is not the instance of Swift")
}

// Type Casting using as? operator
if let res = obj as? Swift {
   print("Successfully casted to Swift")
   res.display()
} else {
   print("Could not cast to Swift")
}

Output

It will produce the following output −

Yes it is the instance of Swift
Successfully casted to Swift
Welcome to Swift tutorial
Advertisements