Lesson 57Structs

Protocols with Structs

What are Protocols?

Protocols define a blueprint of methods and properties that structs (and classes) must implement. They enable polymorphism and code flexibility!

Protocol Syntax

protocol ProtocolName {
    var property: Type { get set }
    func method()
}

Key Concepts

Property Requirements

get (read-only) or get set (read-write)

Method Requirements

Use mutating for value type methods

Protocol Inheritance

Protocols can inherit from others

Protocol as Type

Use protocols for polymorphism

Benefits

  • Define shared behavior across types
  • Enable polymorphism without inheritance
  • Create flexible, testable code
  • Composition over inheritance
main.swift
// PROTOCOLS WITH STRUCTS
// Protocols define a blueprint of methods and properties

// DEFINING A PROTOCOL
protocol Drawable {
    func draw()
}

protocol Describable {
    var description: String { get }
}

// CONFORMING TO PROTOCOLS
struct Circle: Drawable, Describable {
    var radius: Double

    func draw() {
        print("Drawing a circle with radius \(radius)")
    }

    var description: String {
        return "Circle with radius \(radius)"
    }
}

struct Rectangle: Drawable, Describable {
    var width: Double
    var height: Double

    func draw() {
        print("Drawing rectangle \(width)x\(height)")
    }

    var description: String {
        return "Rectangle \(width)x\(height)"
    }
}

let circle = Circle(radius: 5)
circle.draw()  // Drawing a circle with radius 5
print(circle.description)

// PROTOCOL WITH REQUIREMENTS
protocol Vehicle {
    var numberOfWheels: Int { get }
    var maxSpeed: Double { get set }

    func start()
    func stop()
}

struct Car: Vehicle {
    var numberOfWheels: Int = 4
    var maxSpeed: Double

    func start() {
        print("Car engine started!")
    }

    func stop() {
        print("Car stopped.")
    }
}

// PROTOCOL WITH MUTATING METHODS
protocol Toggleable {
    mutating func toggle()
}

struct LightSwitch: Toggleable {
    var isOn: Bool = false

    mutating func toggle() {
        isOn.toggle()
        print("Light is \(isOn ? "ON" : "OFF")")
    }
}

var light = LightSwitch()
light.toggle()  // Light is ON
light.toggle()  // Light is OFF

// PROTOCOL INHERITANCE
protocol Named {
    var name: String { get }
}

protocol Aged {
    var age: Int { get }
}

protocol Person: Named, Aged {
    func introduce()
}

struct Student: Person {
    var name: String
    var age: Int

    func introduce() {
        print("Hi, I'm \(name), \(age) years old")
    }
}

// USING PROTOCOLS AS TYPES
func drawAll(_ shapes: [Drawable]) {
    for shape in shapes {
        shape.draw()
    }
}

let shapes: [Drawable] = [
    Circle(radius: 3),
    Rectangle(width: 4, height: 2)
]
drawAll(shapes)

Try It Yourself!

Create a Playable protocol with play() and pause() methods. Implement it for Music and Video structs!