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

Protocol Composition

Protocol composition lets you say a type must check off items from more than one checklist at the same time, combining them with an ampersand.
Syntax
swift
func functionName(_ param: ProtocolA & ProtocolB) {
    // param has members of both protocols
}

func other(_ param: ProtocolA & ProtocolB & ProtocolC) { }

Requiring Multiple Protocols with &

A function parameter typed as ProtocolA & ProtocolB accepts only values conforming to both protocols simultaneously.

Example: Requiring Multiple Protocols with &

markup
// Define a protocol `Named` describing required behavior
protocol Named {
    var name: String { get }
}
// Define a protocol `Aged` describing required behavior
protocol Aged {
    var age: Int { get }
}
// Define a struct `Person`
struct Person: Named, Aged {
    var name: String
    var age: Int
}
// Define the function `describe` taking `value` and returning a String
func describe(_ value: Named & Aged) -> String {
    // Return `"\(value.name) is \(value.age) years old"` from this function
    return "\(value.name) is \(value.age) years old"
}
// Declare a constant `person`, set to `Person(name: "Lee", age: 40)`
let person = Person(name: "Lee", age: 40)
// Print `describe(person)` to the console
print(describe(person))

Composition with Three or More Protocols

Protocol composition isn't limited to two protocols -- any number can be combined with additional & operators.

Example: Composition with Three or More Protocols

markup
// Define a protocol `Named` describing required behavior
protocol Named { var name: String { get } }
// Define a protocol `Aged` describing required behavior
protocol Aged { var age: Int { get } }
// Define a protocol `Employed` describing required behavior
protocol Employed { var job: String { get } }
// Define a struct `Worker`
struct Worker: Named, Aged, Employed {
    var name: String
    var age: Int
    var job: String
}
// Define the function `introduce` taking `value`
func introduce(_ value: Named & Aged & Employed) {
    // Print "\(value.name), \(value.age), works as \(value.job)" to the console
    print("\(value.name), \(value.age), works as \(value.job)")
}
introduce(Worker(name: "Kai", age: 33, job: "Engineer"))
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. Trying to use inheritance-style syntax to require multiple protocols; composition uses & between protocol names, not commas in a type annotation.
  2. Forgetting a composed type (ProtocolA & ProtocolB) requires an instance to conform to BOTH protocols, not just one of them.
  3. Overcomplicating a function signature with many composed protocols when a single custom protocol combining the requirements would be clearer.
Chapter Summary
  • ProtocolA & ProtocolB describes a type conforming to both protocols at once.
  • This is commonly used as a parameter type to require multiple capabilities.
  • Composition differs from class inheritance, which only allows one superclass.
  • You can compose any number of protocols together with &.
🔒

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.