Swift Class

Swift Class is a blueprint or template for an instance of that class. The term object is often used to refer to an instance of a class.

An instance of a class is traditionally known as an object. However, in Swift classes and structures are much closer in functionality than in other languages. Hence we use the words instance and objects interchangeably.

Swift Class Syntax

import Foundation

class TestClass {
    
    var str = "Hello, playground"
    var number = 1

}

Creating an instance of the class as shown below.

import Foundation
class TestClass { var str = "Hello, playground" var number = 1 } var obj = TestClass() print(obj.str) //prints Hello, playground print(obj.number) //prints 1

Swift Class Initializers

Unlike Structs(Swift Struct), Classes don’t have default Initializers. We’ll need to create our own initializers and assign values to the properties in them.
The code snippet below contains a class with an initializer.

import Foundation

class TestClass {
    
    var str: String
    var number: Int
    
    init(str: String, number: Int) {
        self.str = str
        self.number = number
    }

}

var obj = TestClass(str: "Hello World",number: 2)
print("Default String is \(obj.str) and Default number is \(obj.number)")

[quote font=”helvetica” font_style=”italic”]Note: A compiler error would occur if any of the declared properties aren’t initialized in a class.[/quote]

Declare multiple initializers in your class as shown below.

import Foundation

class TestClass {
    
    var str: String
    var number: Int
    
    init(str: String, number: Int) {
        self.str = str
        self.number = number
    }
    
    init() {
        str = "Declare as many initalisers as you want"
        number = 0
    }

}

var obj = TestClass(str: "Hello World",number: 2)
print("Default String is \(obj.str) and Default number is \(obj.number)")

var obj2 = TestClass()
print("Default String is \(obj2.str) and Default number is \(obj2.number)") 

Swift Classes Inheritance

Let’s create a base class as shown below.

import Foundation

class Animal {
    
    var isVeg: Bool
    var eats: String
    var numberOfLegs: Int
    
    init(isVeg: Bool, eats: String, numberOfLegs: Int) {
        self.isVeg = isVeg
        self.eats = eats
        self.numberOfLegs = numberOfLegs
    }
    
    func printProperties() {
        print("Is Veg? \(isVeg). Eats: \(eats). Number of legs: \(numberOfLegs)")
    }
}

So Animal is the base class that’ll be inherited by our subclasses. Before we get down to them, let’s try creating an instance of the above class and calling the instance method over it as shown below.

var anim = Animal(isVeg: false, eats: "Can eat you", numberOfLegs: 4)
anim.printProperties() //prints Is Veg? false. Eats: Can eat you. Number of legs: 4

To extend the superclass in the subclass, we write the subclass name followed by a colon and then the superclass name as shown below.

class Tiger: Animal {
    //Add class specific implementation
}

Without setting anything in the subclass, we can create an instance of Tiger class with the initializer of the superclass. To access the properties and functions of the superclass the dot operator is used.

var tiger = Tiger(isVeg: false, eats: "Can eat you", numberOfLegs: 4)
tiger.printProperties() //prints Is Veg? false. Eats: Can eat you. Number of legs: 4

To override the functions of the superclass, we use the keyword override in the subclass as shown below.

class Tiger: Animal {
    
    override func printProperties() {
        super.printProperties()
        print("This is Subclass Tiger")
    }
    
}

var tiger = Tiger(isVeg: false, eats: "Can eat you", numberOfLegs: 4)
tiger.printProperties()
//Is Veg?: false. Eats: Can eat you. Number of legs: 4
//This is Subclass Tiger

To access properties/functions of the superclass inside the class we use the super keyword followed by the dot operator. If the function printProperties in the Animal class is set to final, it can’t be overridden and will lead to a compilation error.

import Foundation

class Animal {
    
    var isVeg: Bool
    var eats: String
    var numberOfLegs: Int
    
    init(isVeg: Bool, eats: String, numberOfLegs: Int) {
        self.isVeg = isVeg
        self.eats = eats
        self.numberOfLegs = numberOfLegs
    }
    
    final func printProperties() {
        print("Is Veg?: \(isVeg). Eats: \(eats). Number of legs: \(numberOfLegs)")
    }
}

class Tiger: Animal {
    
    //Error: Instance method overrides a 'final' instance method
    override func printProperties() {
        super.printProperties()
        print("This is Subclass Tiger")
    }
    
}

var tiger = Tiger(isVeg: false, eats: "Can eat you", numberOfLegs: 4)
tiger.printProperties() //Error: Ambiguous use of 'printProperties()'
In the following code, we place properties inside a subclass and create it’s own init
import Foundation

class Animal {
    
    var isVeg: Bool
    var eats: String
    var numberOfLegs: Int
    
    init(isVeg: Bool, eats: String, numberOfLegs: Int) {
        self.isVeg = isVeg
        self.eats = eats
        self.numberOfLegs = numberOfLegs
    }
    
    func printProperties() {
        print("Is Veg?: \(isVeg). Eats: \(eats). Number of legs: \(numberOfLegs)")
    }
}

class Tiger: Animal {
    
    var color: String
    
    init(isVeg: Bool, eats: String, numberOfLegs: Int, color: String) {
        self.color = color
        super.init(isVeg: isVeg, eats: eats, numberOfLegs: numberOfLegs)
    }
    
    override func printProperties() {
        print("Is Veg? \(isVeg). Eats: \(eats). Number of legs: \(numberOfLegs). Color is \(color).")
    }
}
var tiger = Tiger(isVeg: false, eats: "Can eat you", numberOfLegs: 4, color: "White")
tiger.printProperties() //prints Is Veg? false. Eats: Can eat you. Number of legs: 4. Color is White.
In the above code, we add another property color to the subclass. super.init is called to initalise the properties of the superclass once the subclass properties are initialised.

Swift Classes are Reference Types

Unlike Structs, Classes are passed by reference and not value. Let’s set the above tiger instance to another variable and change its properties.

var tiger = Tiger(isVeg: false, eats: "Can eat you", numberOfLegs: 4, color: "White")
var tiger1 = tiger
tiger1.color = "Yellow"
tiger.printProperties()   //Is Veg? false. Eats: Can eat you. Number of legs: 4. Color is Yellow.
tiger1.printProperties()   //Is Veg? false. Eats: Can eat you. Number of legs: 4. Color is Yellow.

The output on printing the property color on both the tiger and tiger1 instances is the same because tiger1 is not a copy of the tiger. It is the same as tiger.

Convenience Initializers

Convenience Initializers act as supporting initializers for the main initializers of the class. These are primarily used to set default values in the main initializers. Convenience Initializers require the keyword convenience before init as shown below.

import Foundation

class TestClass {

    var eyes: Int
    var legs: Int
    init(eyes: Int, legs: Int)
    {
        self.eyes = eyes
        self.legs = legs
    }
    convenience init() {
        self.init(eyes: 2, legs: 4)
    }
    
}

var obj = TestClass()
print(obj.eyes) //prints 2
print(obj.legs) //prints 4

[quote font=”helvetica”]Note: Convenience initializers are only valid when a normal initializer was already declared in the class A convenience initializer must call another initializer from the same class.[/quote]

2 Responses