EZ

Eduzan

Learning Hub

Back to SWIFT

Swift OOPs: Object-Oriented Programming in Swift

Published 2025-12-16

Swift

Swift supports object-oriented programming through classes, and it also provides powerful value-type alternatives such as structures and enumerations. Understanding how types, properties, methods, initialization, and memory management work is essential for writing clean and scalable Swift code.


Structures in Swift

A struct groups related data and behavior into a single type. Structures are value types, meaning they are copied when assigned or passed into functions.

Structure Syntax

struct StructureName {
    // properties and methods
}

Example: Defining and Creating a Struct

struct Employee {
    var name: String
    var id: Int
    var department: String
    var joiningYear: Int
}

let employee = Employee(name: "Mohit", id: 1234, department: "HR", joiningYear: 2019)
print(employee.name)
print(employee.joiningYear)

Memberwise Initializers in Structs

Swift automatically generates a memberwise initializer for structs.

struct Employee {
    var name: String
    var id: Int
}

let updated = Employee(name: "Mohit", id: 5678)
print(updated.id)

Methods in Structures

Structs can contain methods (functions inside types).

struct Salary {
    var baseSalary: Int

    func calculateIncrement() {
        let newSalary = 2 * baseSalary
        print("New Salary: \(newSalary)")
    }
}

let salary = Salary(baseSalary: 230000)
salary.calculateIncrement()

Using self in Swift

self refers to the current instance. It’s especially useful when parameter names match property names.

struct Article {
    var count = 230

    func update(count: Int = 23) {
        print("Parameter count: \(count)")
        print("Stored count: \(self.count)")
    }
}

Article().update()

Properties in Swift

Properties store or compute values inside a type. The most common types are:

  • Stored properties (saved in memory)
  • Computed properties (calculated via getters/setters)
  • Lazy properties (initialized only when first used)
  • Property observers (run when values change)

Stored Properties

struct Person {
    var name: String
}

let person = Person(name: "John")
print(person.name)

Lazy Stored Properties

Lazy properties are useful when initialization is expensive.

class Course {
    var courseName: String

    lazy var description: String = {
        "Course: \(courseName)"
    }()

    init(courseName: String) {
        self.courseName = courseName
    }
}

let course = Course(courseName: "Swift")
print(course.description)

Computed Properties

Computed properties calculate a value instead of storing it.

struct Rectangle {
    var length: Double
    var width: Double

    var perimeter: Double {
        get { 2 * (length + width) }
        set { length = (newValue / 2) - width }
    }
}

var rect = Rectangle(length: 10, width: 5)
print(rect.perimeter)
rect.perimeter = 40
print(rect.length)

Read-Only Computed Properties

struct Cuboid {
    var width: Double
    var height: Double
    var depth: Double

    var volume: Double {
        width * height * depth
    }
}

let box = Cuboid(width: 4, height: 4, depth: 4)
print(box.volume)

Property Observers (willSet, didSet)

class StepCounter {
    var totalSteps: Int = 0 {
        willSet { print("About to set total steps to \(newValue)") }
        didSet {
            if totalSteps > oldValue {
                print("Added \(totalSteps - oldValue) steps")
            }
        }
    }
}

let counter = StepCounter()
counter.totalSteps = 105
counter.totalSteps = 240

Methods in Swift

Methods are functions associated with a type. Swift supports:

  • Instance methods (called on objects)
  • Type methods (called on the type itself)

Instance Methods Example

class Calculator {
    let result: Int

    init(x: Int, y: Int) {
        self.result = x + y
    }

    func subtract(by value: Int) -> Int {
        result - value
    }
}

let calculator = Calculator(x: 200, y: 300)
print(calculator.subtract(by: 50))

External and Local Parameter Names

class Divider {
    func divide(_ numerator: Int, by denominator: Int) {
        print("Quotient is: \(numerator / denominator)")
    }
}

Divider().divide(120, by: 3)

Mutating Methods in Value Types

Structs need mutating methods to modify stored properties.

struct Rectangle {
    var length: Int
    var width: Int

    mutating func scale(by factor: Int) {
        length *= factor
        width *= factor
        print("Length=\(length), Width=\(width)")
    }
}

var r = Rectangle(length: 4, width: 5)
r.scale(by: 2)

Type Methods (static and class)

class MathOperations {
    class func absoluteValue(of number: Int) -> Int {
        number < 0 ? -number : number
    }
}

struct Utility {
    static func absoluteValue(of number: Int) -> Int {
        number < 0 ? -number : number
    }
}

print(MathOperations.absoluteValue(of: -10))
print(Utility.absoluteValue(of: -20))

Function vs Method in Swift

  • A function is standalone (global or local scope)
  • A method belongs to a type (class/struct/enum)

Function Example

func greet() {
    print("Hello Swift!")
}

greet()

Method Example

struct Developer {
    let speed: Int
    func learn() { print("Learning at \(speed) MPH") }
    static func code() { print("Writing Swift code") }
}

Developer(speed: 15).learn()
Developer.code()

Deinitialization in Swift (deinit)

Only classes support deinitializers because classes use ARC (Automatic Reference Counting).

var x = 10

class DeinitializerExample {
    init() { x += 10 }
    deinit { x = 0 }
}

var obj: DeinitializerExample? = DeinitializerExample()
print("Before deinit: \(x)")
obj = nil
print("After deinit: \(x)")

Typecasting in Swift

Typecasting helps you check or convert types at runtime.

Upcasting (Safe)

class Animal { func sound() { print("Animal sound") } }
class Dog: Animal { override func sound() { print("Woof") } }

let dog = Dog()
let animal: Animal = dog
animal.sound()

Type Checking with is

let value: Any = 42
if value is Int {
    print("value is an Int")
}

Downcasting with as? and as!

class Vehicle { }
class Car: Vehicle { var brand = "Tesla" }

let v: Vehicle = Car()
if let c = v as? Car {
    print(c.brand)
}

Summary

Swift supports OOP through classes and complements it with powerful value types like structs. Key topics covered:

  • Structs (value types) and how they work
  • Stored, computed, lazy properties and observers
  • Instance methods, type methods, and mutating
  • Functions vs methods
  • ARC and deinit
  • Typecasting with is, as?, and as!