Understanding Classes in Swift
Introduction
In Swift, a class is a fundamental building block of object-oriented programming (OOP). Classes allow developers to create reusable code structures that define properties and methods, enabling efficient code organization and management. Unlike structures (structs), classes support inheritance, reference types, and deinitialization, making them a powerful choice for building robust applications.
Understanding Swift classes is essential for writing scalable and maintainable code, especially when working with complex data models and object-oriented principles.
Why Use Classes in Swift?
- Encapsulation: Organize code into reusable units.
- Inheritance: A class can inherit properties and methods from another class.
- Reference Type: Unlike structs, classes are stored as references.
- Deinitialization: Classes can implement a deinitializer (deinit) to free resources when an instance is no longer needed.
- Polymorphism: Methods can be overridden in subclasses to change behavior dynamically.
Class vs. Struct in Swift
Feature | Class | Struct |
---|---|---|
Reference Type | Yes | No (Value Type) |
Inheritance | Yes | No |
Deinitialization | Yes | No |
Mutability | Can be mutable | Immutable by default |
Stored in Heap | Yes | No (Stack) |
Syntax of a Class in Swift
class ClassName {
var property: String
init(property: String) {
self.property = property
}
func display() {
print("Property
Value: \(property)")
}
}
Example 1: Creating a Simple Class
import Foundation
class Car {
var brand: String
var model: String
var year: Int
init(brand: String, model: String, year: Int) {
self.brand = brand
self.model = model
self.year = year
}
func carDetails() {
print("Car:
\(brand) \(model) - Year: \(year)")
}
}
// Creating an object of the class
let myCar = Car(brand: "Tesla", model: "Model S", year: 2024)
myCar.carDetails()
Output
Example 2: Using Class Inheritance in Swift
Inheritance allows a class to inherit properties and methods from another class, enabling code reuse and extensibility.
import Foundation
class Vehicle {
var speed: Int
init(speed: Int) {
self.speed = speed
}
func move() {
print("Moving at
\(speed) km/h")
}
}
class Bike: Vehicle {
var type: String
init(speed: Int, type: String) {
self.type = type
super.init(speed: speed)
}
override func move() {
print("\(type)
bike moving at \(speed) km/h")
}
}
let myBike = Bike(speed: 80, type: "Sports")
myBike.move()
Output
Example 3: Swift Class with Computed Properties
import Foundation
class Rectangle {
var width: Double
var height: Double
init(width: Double, height: Double) {
self.width = width
self.height = height
}
var area: Double {
return width * height
}
}
let rect = Rectangle(width: 10, height: 5)
print("Area: \(rect.area)")
Output
Example 4: Swift Class with deinit Method
The deinit
method is called automatically when an instance of a class is deallocated.
import Foundation
class FileManager {
let fileName: String
init(fileName: String) {
self.fileName = fileName
print("\(fileName) opened")
}
deinit {
print("\(fileName) closed")
}
}
var file: FileManager? = FileManager(fileName: "document.txt")
file = nil // Object deallocated, `deinit` called
Output
document.txt closed
Example 5: Using Class Methods (Static Methods)
Static methods belong to the class itself, not an instance.
import Foundation
class MathUtils {
static func square(_ number: Int)
-> Int {
return number * number
}
}
print(MathUtils.square(5)) //
25
Output
Best Practices for Using Classes in Swift
- Use classes when reference semantics are needed (e.g., shared state).
- Use structs when working with immutable data to avoid unnecessary memory overhead.
- Avoid unnecessary inheritance; prefer composition over inheritance when possible.
- Use
final
for classes that should not be inherited for performance optimizations. - Implement
deinit
only when necessary to free up resources.