A class in Swift, like classes in other programming languages, serves as a blueprint for creating objects that encapsulate data and behaviour. In Swift, you will see both classes and structs. This post will primarily focus on classes, although I will mention structs throughout to highlight some of the differences.
Classes are reference types, meaning that if you instantiate it, and then make a copy of it, any changes to either copy will be reflected in the other copy.
class Car {
var model: String
init(model: String) {
self.model = model
}
}
let car1 = Car(model: "Ferrari")
let car2 = car1
car2.model = "Lamborghini"
print(car1.model)
Although we changed car2’s model, because car2 is a copy of car1, and that it copies by reference, any changes to car2 here will also be changing car1.
Inheritance
Classes support inheritance:
class Vehicle {
var model: String
init(model: String) {
self.model = model
}
func description() -> String {
return "This is a \(model)."
}
}
class Car: Vehicle {
var numberOfDoors: Int
init(model: String, numberOfDoors: Int) {
self.numberOfDoors = numberOfDoors
super.init(model: model)
}
override func description() -> String {
return "Car model: \(model) with \(numberOfDoors) doors."
}
}
class Bike: Vehicle {
var gears: Int
init(model: String, gears: Int) {
self.gears = gears
super.init(model: model)
}
override func description() -> String {
return "Bike model: \(model) with \(gears) gears."
}
}
let car = Car(model: "Tesla Model S", numberOfDoors: 4)
let bike = Bike(model: "Cannondale", gears: 21)
print(car.description()) // Car model: Tesla Model S with 4 doors.
print(bike.description()) // Bike model: Cannondale with 21 gears.
The example above shows inheritance. We have a Bike class and a Car class. Both of them inherit from the Vehicle class given that they are both types of vehicle. Both the Car and the Bike can set the model, and both of them override the description so that it suits the type of class, so in the example above, the bike.description call prints “Bike model: …” and the car.description prints “Car model: …”.
A class can only inherit from a single class, although it can conform to multiple protocols as we will see in the next example.
Conforming to Protocols
As well as inheriting from a parent class, a class can also adopt a protocol. Protocols are used quite often in Swift and SwiftUI. Like a class is a blueprint, a protocol defines a blueprint. When a class adopts a protocol, the protocol defines what methods and properties are required.
A protocol is added in the same way as inheritance is added:
protocol Startable {
func startEngine()
}
protocol Steerable {
func steer(direction: String)
}
protocol Movable {
func move(speed: Int)
}
class Car: Vehicle, Startable, Steerable, Movable {
...
class Bike: Vehicle, Steerable, Movable {
...
In the example above, we declare three protocols. The Car adopts all three, whereas the Bike doesn’t adopt Startable.
When you adopt one or more protocols, you will likely get a red warning appear informing you that “Type ‘Car’ does not comform to protocol ‘Movable’… in this case.
Because we adopted this protocol, we must implement the required methods and properties, in this case, Movable requires we implement function move(speed: Int).

Clicking on the red error opens up a panel where you can click on Fix to automatically add anything thats missing. It is up to you to implement how the engine starts.

Properties and Methods
Classes have properties and methods.
Properties define the state. In the example above, the state it would store includes the model, but could also include the speed, number of wheels, as well as many other items.
Properties can be stored, as seen with the “model” earlier. The value is held within the class. They can also be computed where no value is stored, but when you get the property, it calculates it and then returns that to you.
var year: Int
var carAge: Int {
let currentYear = 2025
return currentYear - year
}
The example above is a computed property. It uses the year of the vehicle, and then works out its age by taking that away from the current year. The first property, year, is not computed and would just return the value it was given when the class was created, or if someone has adjusted the year.
Methods define the behaviour of a class, such as func moveVehicle(direction….), or as seen in the description method created earlier. There are two types, instance methods and class methods.
The method above is an instance method which is used to modify the instance of the class such as “myCar.move(forward…)”.
static func showNumberOfCars() {
print("Total cars: \(numberOfCars)")
}
The method above is a class method and is called with Car.showNumberOfCard(). It is declared as static to make it a class method. There are times when you do not need to instantiate an object just so that you can get some information about it. For these times, a class method is suitable.
This article covered some of the basics of classes and is enough to get you started, although there is more to classes which will discuss later.
Leave a Reply
You must be logged in to post a comment.