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?, andas!
Leave a Reply