Skip to main content

Swift Classes Basics

Classes are one of the fundamental building blocks in Swift and form the backbone of Object-Oriented Programming (OOP). In this guide, we'll explore what classes are, how to create and use them, and why they're essential for iOS and macOS development.

What is a Class?

In Swift, a class is a blueprint for creating objects (instances) that combine data (properties) and functionality (methods). Unlike structs, classes are reference types, meaning when you pass a class instance around, you're passing a reference to the same instance rather than creating a copy.

Classes provide important features such as:

  • Inheritance
  • Reference counting
  • Type casting
  • Deinitialization

Creating a Basic Class

Let's start by creating a simple class:

swift
class Person {
// Properties
var name: String
var age: Int

// Initializer
init(name: String, age: Int) {
self.name = name
self.age = age
}

// Method
func introduce() {
print("Hello, my name is \(name) and I'm \(age) years old.")
}
}

This Person class has:

  • Two properties: name and age
  • An initializer that sets up these properties
  • A method called introduce() that prints a greeting

Creating and Using Class Instances

To create an instance of our class and use it:

swift
// Creating an instance
let john = Person(name: "John", age: 25)

// Accessing properties
print(john.name) // Output: John
print(john.age) // Output: 25

// Calling a method
john.introduce() // Output: Hello, my name is John and I'm 25 years old.

// Modifying a property
john.age = 26
john.introduce() // Output: Hello, my name is John and I'm 26 years old.

Class Properties

Classes can have different types of properties:

Stored Properties

These store constant and variable values as part of a class instance:

swift
class Rectangle {
var width: Double
var height: Double

init(width: Double, height: Double) {
self.width = width
self.height = height
}
}

Computed Properties

These don't actually store a value but provide a getter and optional setter:

swift
class Rectangle {
var width: Double
var height: Double

// Computed property
var area: Double {
return width * height
}

init(width: Double, height: Double) {
self.width = width
self.height = height
}
}

let rectangle = Rectangle(width: 5.0, height: 10.0)
print(rectangle.area) // Output: 50.0

Property Observers

These observe and respond to changes in a property's value:

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

let stepCounter = StepCounter()
stepCounter.totalSteps = 200
// Output: About to set totalSteps to 200
// Output: Added 200 steps

stepCounter.totalSteps = 360
// Output: About to set totalSteps to 360
// Output: Added 160 steps

Class Methods

Methods are functions that are associated with a particular class:

swift
class Calculator {
func add(a: Int, b: Int) -> Int {
return a + b
}

func subtract(a: Int, b: Int) -> Int {
return a - b
}
}

let calc = Calculator()
print(calc.add(a: 5, b: 3)) // Output: 8
print(calc.subtract(a: 10, b: 4)) // Output: 6

Type Properties and Methods

Classes can also have properties and methods that belong to the class itself, not to instances of the class:

swift
class Temperature {
static var defaultUnit = "Celsius"

var degrees: Double

init(degrees: Double) {
self.degrees = degrees
}

static func convertToCelsius(fahrenheit: Double) -> Double {
return (fahrenheit - 32) * 5/9
}
}

// Accessing a type property
print(Temperature.defaultUnit) // Output: Celsius

// Using a type method
let celsiusTemp = Temperature.convertToCelsius(fahrenheit: 98.6)
print(celsiusTemp) // Output: 37.0

Class Inheritance

One of the most powerful features of classes is inheritance, where a class can inherit properties and methods from another class:

swift
class Vehicle {
var currentSpeed = 0.0

func description() -> String {
return "traveling at \(currentSpeed) miles per hour"
}
}

class Bicycle: Vehicle {
var hasBasket = false
}

let bicycle = Bicycle()
bicycle.currentSpeed = 15.0
print("Bicycle is \(bicycle.description())") // Output: Bicycle is traveling at 15.0 miles per hour

Reference vs. Value Types

An important distinction to understand is that classes are reference types, unlike structs which are value types:

swift
class SampleClass {
var value = 10
}

let classA = SampleClass()
let classB = classA // classB points to the same instance as classA

classB.value = 20

print(classA.value) // Output: 20
print(classB.value) // Output: 20

When you assign a class instance to another variable, both variables point to the same instance. Changes to one affect the other.

Real-World Example: A Simple Game Character

Let's create a more comprehensive example of a game character class:

swift
class GameCharacter {
var name: String
var health: Int
var level: Int

init(name: String) {
self.name = name
self.health = 100
self.level = 1
}

func attack(target: GameCharacter, damage: Int) {
target.takeDamage(amount: damage)
print("\(name) attacks \(target.name) for \(damage) damage!")
}

func takeDamage(amount: Int) {
health -= amount
if health < 0 {
health = 0
}

print("\(name)'s health is now \(health)")

if health == 0 {
print("\(name) has been defeated!")
}
}

func levelUp() {
level += 1
health = 100 + (level * 10)
print("\(name) leveled up to level \(level)! Health increased to \(health).")
}
}

// Using our game character
let hero = GameCharacter(name: "Hero")
let enemy = GameCharacter(name: "Enemy")

hero.attack(target: enemy, damage: 30)
// Output: Hero attacks Enemy for 30 damage!
// Output: Enemy's health is now 70

hero.levelUp()
// Output: Hero leveled up to level 2! Health increased to 120.

enemy.attack(target: hero, damage: 25)
// Output: Enemy attacks Hero for 25 damage!
// Output: Hero's health is now 95

Summary

In this guide, we've covered the basics of Swift classes:

  • Creating and using classes
  • Properties (stored, computed, and observers)
  • Methods and type methods
  • Inheritance
  • Reference behavior

Classes are essential in Swift programming and form the foundation of iOS app development. They allow you to create reusable, encapsulated code components that model real-world objects and concepts.

Exercises

To reinforce your understanding of classes, try these exercises:

  1. Create a BankAccount class with properties for account number, owner name, and balance. Add methods for deposit and withdrawal.

  2. Create a Shape class with subclasses for different shapes (Circle, Rectangle, Triangle). Each should have appropriate properties and a method to calculate area.

  3. Create a Library class that can store and manage Book objects. Include functionality to check out and return books.

Additional Resources

Understanding classes is crucial as you develop more complex Swift applications. In the next section, we'll dive deeper into inheritance and explore how it can create sophisticated class hierarchies.



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)