Protocols
Protocols are Swift's way of describing what a type can do without saying how. You'll define and adopt protocols, list property and method requirements, use a protocol as a type, and add shared default behaviour with protocol extensions.
Learn Protocols in our free Swift course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Swift course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn in This Lesson
- • Define a protocol with property and method requirements
- • Adopt a protocol on a struct, class, or enum
- • Conform to multiple protocols at once
- • Use a protocol as a type for variables and arrays
- • Provide default implementations via protocol extensions
- • Recognize built-in protocols like Equatable
1️⃣ Defining & Adopting a Protocol
A protocol lists requirements — properties and methods — with no bodies. A type adopts it by listing it after a colon and then conforming : providing an implementation for every requirement.
2️⃣ Protocol as a Type
Once several types conform to the same protocol, you can treat them uniformly by using the protocol as a type — for example an array of Animal holding both dogs and cats.
3️⃣ Default Implementations
A protocol extension can supply default behaviour. Conformers inherit it automatically and may override it. This is how Swift shares code without class inheritance.
4️⃣ Conforming to Multiple Protocols
A type can conform to several protocols, and a parameter can require a composition of them with & (e.g. Named & Aged ).
Your turn. Fill in the blanks to conform to a protocol and implement its method.
Pro Tips
- 💡 Name protocols by capability. Drawable , Comparable , Codable describe what a type can do.
- 💡 Put shared logic in extensions. Defaults keep conformers small.
- 💡 Prefer small protocols. Many focused protocols compose better than one giant one.
- 💡 Let the compiler synthesize Equatable / Hashable when possible.
Common Errors (and the fix)
- "Type 'X' does not conform to protocol 'Y'" — a requirement is missing or has the wrong signature. Implement every member exactly.
- "Protocol 'Y' requirement 'name' cannot be satisfied by a non-final class" — usually a signature mismatch; match the declared types.
- Read-only property declared as let in the protocol — declare protocol properties with var ... { get } , not let .
- Forgetting the colon — adopt with struct Dog: Animal , not a keyword like extends.
📋 Quick Reference
Task
Code
Note
Define
protocol P { func f() }
requirements only
Adopt
struct S: P { … }
after a colon
Read-only prop
var x: Int { get }
in protocol
Default
extension P { func f() { … } }
shared behaviour
Compose
A & B
needs both
Frequently Asked Questions
Mini-Challenge: Describable
No blanks this time — just a brief and an outline. Build it, run it, and check your output against the example in the comments.
🎉 Lesson Complete!
- ✅ Protocols declare requirements; types conform by implementing them
- ✅ Adopt with a colon: struct Dog: Animal
- ✅ A protocol can be used as a type to store any conformer
- ✅ Protocol extensions supply default implementations
- ✅ Types can conform to many protocols at once
- ✅ Next lesson: Extensions
Practice quiz
What is a protocol in Swift?
- A concrete class
- A kind of optional
- A blueprint of requirements that a type can adopt
- A global function
Answer: A blueprint of requirements that a type can adopt. A protocol defines a set of requirements (methods, properties) that conforming types must implement.
What keyword declares that a type adopts a protocol?
- There's no keyword — you list it after a colon
- implements
- extends
- uses
Answer: There's no keyword — you list it after a colon. You adopt a protocol by listing it after a colon: struct Dog: Animal { ... }.
Can a Swift type conform to multiple protocols?
- No, only one
- Only classes can
- Only via inheritance
- Yes, by separating them with commas
Answer: Yes, by separating them with commas. A type can conform to many protocols, listed comma-separated: struct X: A, B, C.
How do you require a read-only property in a protocol?
- let name: String
- var name: String { get }
- func name() -> String only
- var name: String { set }
Answer: var name: String { get }. Protocol properties are declared as var with { get } for read-only, or { get set } for read-write.
Can you use a protocol as a type for a variable?
- Yes — a variable can be typed as the protocol, holding any conforming value
- No, never
- Only inside extensions
- Only for classes
Answer: Yes — a variable can be typed as the protocol, holding any conforming value. A protocol can be used as a type, so a variable of that protocol type can hold any conforming instance.
How do you provide a DEFAULT implementation of a protocol method?
- In the protocol body directly
- In a subclass only
- In a protocol extension
- You can't — it must always be implemented
Answer: In a protocol extension. Default implementations live in a protocol extension, so conformers inherit them unless they override.
What does it mean for a struct to 'conform to' a protocol?
- It inherits its stored properties
- It provides implementations for all the protocol's requirements
- It becomes a class
- It copies the protocol's code
Answer: It provides implementations for all the protocol's requirements. Conforming means the type supplies implementations for every requirement the protocol declares.
Which built-in protocol lets you compare instances with ==?
- Comparable
- Hashable
- Codable
- Equatable
Answer: Equatable. Equatable provides ==. Comparable adds < ordering; Hashable enables use in sets/dictionaries.
Can a protocol require a method WITHOUT providing its body?
- No
- Yes — it declares the signature; conformers supply the body
- Only for static methods
- Only in classes
Answer: Yes — it declares the signature; conformers supply the body. A protocol declares method signatures only; conforming types provide the actual implementation.
What happens if a type claims conformance but misses a requirement?
- It compiles with a warning
- The requirement is auto-generated
- It is a compile-time error
- It runs but crashes
Answer: It is a compile-time error. Missing a required member is a compile-time error — the compiler enforces full conformance.
Continue this course
- Previous: map, filter & reduce
- Next: Extensions