Swift Classes and Inheritance

A class is similar to a struct but with key differences. Classes are reference types — multiple variables can point to the same instance. Classes also support inheritance, letting one class build on another.

Struct vs Class – The Key Difference


┌──────────────────────────────────────────────────┐
│  Struct (Value Type)                             │
│  var a = Point(x:1)                              │
│  var b = a  → b gets its OWN copy                │
│  Changing b does NOT affect a                    │
│                                                  │
│  Class (Reference Type)                          │
│  var a = Dog()                                   │
│  var b = a  → b POINTS to same dog               │
│  Changing b DOES affect a                        │
└──────────────────────────────────────────────────┘

Defining a Class

class Animal {
    var name: String
    var sound: String

    init(name: String, sound: String) {
        self.name = name
        self.sound = sound
    }

    func speak() {
        print("\(name) says \(sound)")
    }
}

let dog = Animal(name: "Dog", sound: "Woof")
dog.speak()   // Dog says Woof

Unlike structs, classes do not get a free memberwise initializer — you write your own init method.

Reference Type Behaviour

let petA = Animal(name: "Cat", sound: "Meow")
let petB = petA           // petB points to the same object

petB.name = "Tiger"
print(petA.name)          // Tiger ← petA also changed!

Both petA and petB reference the same object in memory. Changing one changes both.

Inheritance – Building on Existing Classes


┌──────────────────────────────────────────────────┐
│  Inheritance Tree                                │
│                                                  │
│         Animal (parent / superclass)             │
│         name, sound, speak()                     │
│              │                                   │
│      ┌───────┴───────┐                           │
│    Dog              Cat   (child / subclass)     │
│    fetch()          purr()                       │
│                                                  │
│  Dog and Cat get everything Animal has,          │
│  plus their own unique abilities.                │
└──────────────────────────────────────────────────┘
class Dog: Animal {
    var breed: String

    init(name: String, breed: String) {
        self.breed = breed
        super.init(name: name, sound: "Woof")
    }

    func fetch() {
        print("\(name) fetches the ball!")
    }
}

let myDog = Dog(name: "Bruno", breed: "Labrador")
myDog.speak()    // Bruno says Woof   ← inherited
myDog.fetch()    // Bruno fetches the ball!
print(myDog.breed)  // Labrador

super.init calls the parent class initializer. The child class must initialize the parent's properties before adding its own.

Overriding Methods

class Cat: Animal {
    init(name: String) {
        super.init(name: name, sound: "Meow")
    }

    override func speak() {
        print("\(name) purrs softly and says \(sound)")
    }
}

let myCat = Cat(name: "Whiskers")
myCat.speak()   // Whiskers purrs softly and says Meow

The override keyword replaces the parent's method with a new version. Swift requires it explicitly so overrides are never accidental.

Preventing Override with final

class Vehicle {
    final func startEngine() {
        print("Engine started.")
    }
}

// Any subclass trying to override startEngine() gets an error.

Mark a method or class with final to block further subclassing or overriding. This is useful when a behaviour must never change.

Identity Operator ===

let a = Animal(name: "Lion", sound: "Roar")
let b = a
let c = Animal(name: "Lion", sound: "Roar")

print(a === b)   // true  — same object in memory
print(a === c)   // false — different objects, same values

The === operator checks whether two variables point to the identical object — not just equal values. This only works with classes.

When to Use Class vs Struct

Choose StructChoose Class
Simple data modelsObjects with shared state
No inheritance neededInheritance required
Copying is desiredSingle shared instance needed
Default Swift preferenceWorking with UIKit/AppKit

Leave a Comment

Your email address will not be published. Required fields are marked *