← Back to Swift Course | Chapter 9: Inheritance & Protocols | Lesson 4 of 7

Protocol Basics

A protocol is like a checklist of things a type promises to be able to do, without saying exactly how it does them.
Syntax
swift
protocol ProtocolName {
    var property: Type { get }
    func method() -> ReturnType
}

struct TypeName: ProtocolName {
    var property: Type
    func method() -> ReturnType { return value }
}

Defining a Protocol

A protocol declares required properties and methods that any conforming type must implement, without providing an implementation itself.

Example: Defining a Protocol

markup
// Define a protocol `Greetable` describing required behavior
protocol Greetable {
    var name: String { get }
    // Define the function `greet` with no parameters and returning a String
    func greet() -> String
}
// Define a struct `Robot`
struct Robot: Greetable {
    var name: String
    // Define the function `greet` with no parameters and returning a String
    func greet() -> String {
        // Return `"Beep boop, I am \(name)"` from this function
        return "Beep boop, I am \(name)"
    }
}
// Declare a constant `robot`, set to `Robot(name: "R2")`
let robot = Robot(name: "R2")
// Print `robot.greet()` to the console
print(robot.greet())

Multiple Types Conforming to the Same Protocol

Different, unrelated types can all conform to the same protocol, letting you treat them uniformly wherever that protocol is expected.

Example: Multiple Types Conforming to the Same Protocol

markup
// Define a protocol `Greetable` describing required behavior
protocol Greetable {
    var name: String { get }
    // Define the function `greet` with no parameters and returning a String
    func greet() -> String
}
// Define a struct `Human`
struct Human: Greetable {
    var name: String
    // Define the function `greet` with no parameters and returning a `String { "Hi, I am \(name)" }`
    func greet() -> String { "Hi, I am \(name)" }
}
// Define a struct `Robot`
struct Robot: Greetable {
    var name: String
    // Define the function `greet` with no parameters and returning a `String { "Beep, I am \(name)" }`
    func greet() -> String { "Beep, I am \(name)" }
}
// Declare a constant `greeters` (a `[Greetable]`), set to `[Human(name: "Ana"), Robot(name: "R2")]`
let greeters: [Greetable] = [Human(name: "Ana"), Robot(name: "R2")]
// Loop over `greeters`, binding each item to `greeter`
for greeter in greeters {
    // Print `greeter.greet()` to the console
    print(greeter.greet())
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Confusing a protocol (a contract with no implementation) with a class (a concrete type with real implementation); a protocol on its own can't be instantiated.
  2. Forgetting a type must implement every requirement listed in a protocol to conform to it -- partial conformance is a compile error.
  3. Assuming protocols can only be adopted by classes; structs and enums can conform to protocols too.
Chapter Summary
  • A protocol defines a set of method and property requirements without implementing them.
  • Any struct, class, or enum can conform to a protocol by implementing all its requirements.
  • Conformance is declared with : ProtocolName after the type name.
  • Protocols enable polymorphism without requiring class inheritance.
🔒

Chapter Quiz — Complete all 7 topics to unlock

0/7 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.