SyntaxStudy
Sign Up
Swift Beginner 1 min read

Protocol Basics

Protocols define a blueprint of methods, properties, and requirements. Any type (class, struct, enum) can conform to a protocol by implementing all its requirements. This is Swift's primary mechanism for abstraction. Protocols support default implementations via protocol extensions — conforming types get the default unless they override it. This enables powerful composition without inheritance. Protocols can inherit from other protocols, combining requirements. A type must satisfy all inherited requirements.
Example
// Protocol definition
protocol Describable {
    var description: String { get }
    func describe() -> String
}

// Protocol extension with default implementation
extension Describable {
    func describe() -> String {
        return "Description: \(description)"
    }
}

// Struct conforming to protocol
struct Car: Describable {
    var make: String
    var model: String
    var year: Int

    var description: String {
        "\(year) \(make) \(model)"
    }
    // describe() provided by extension
}

// Protocol inheritance
protocol Printable: Describable {
    func print()
}

extension Printable {
    func print() {
        Swift.print(describe())
    }
}

// Protocol composition
protocol Named { var name: String { get } }
protocol Aged  { var age: Int { get } }

func greet(_ person: Named & Aged) -> String {
    "Hello \(person.name), you are \(person.age)"
}

struct Person: Named, Aged {
    let name: String
    let age: Int
}

let alice = Person(name: "Alice", age: 30)
print(greet(alice))

// Protocol as type (existential)
let items: [any Describable] = [Car(make: "Toyota", model: "Camry", year: 2023)]