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
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
// 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())
Login to try C/C++/Java/PHP code in the editor
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
// 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())
}
Login to try C/C++/Java/PHP code in the editor
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
- 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.
- Forgetting a type must implement every requirement listed in a protocol to conform to it -- partial conformance is a compile error.
- Assuming protocols can only be adopted by classes; structs and enums can conform to protocols too.
Chapter Summary
- A
protocoldefines 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
: ProtocolNameafter 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: