📖 Scenario: Imagine you are building a simple app that manages different types of vehicles. Each vehicle can describe itself with a message. You want to make it easy to add new vehicle types without rewriting common code.
🎯 Goal: You will create a protocol called Vehicle with a method to describe the vehicle. Then, you will add a protocol extension that provides a default description. Finally, you will create specific vehicle types that use the default description or provide their own.
📋 What You'll Learn
Create a protocol named Vehicle with a method func description() -> String
Add a protocol extension for Vehicle that provides a default implementation of description()
Create a struct Car that conforms to Vehicle and uses the default description
Create a struct Bicycle that conforms to Vehicle and provides its own description() implementation
Print the descriptions of both Car and Bicycle instances
💡 Why This Matters
🌍 Real World
Protocol extensions with default implementations let you write flexible and reusable code. For example, apps that manage many types of objects can share common behavior easily.
💼 Career
Understanding protocol extensions is important for Swift developers. It helps in writing clean, maintainable code and is widely used in iOS app development.
Progress0 / 4 steps
1
Create the Vehicle protocol
Create a protocol called Vehicle with a method func description() -> String.
Swift
Hint
Use the protocol keyword and declare the method signature without a body.
2
Add a default implementation with a protocol extension
Add a protocol extension for Vehicle that provides a default implementation of description() returning the string "This is a vehicle.".
Swift
Hint
Use extension Vehicle and implement description() with the return string.
3
Create Car and Bicycle structs conforming to Vehicle
Create a struct called Car that conforms to Vehicle and uses the default description(). Then create a struct called Bicycle that conforms to Vehicle and provides its own description() returning "This is a bicycle.".
Swift
Hint
Define Car without adding description() to use the default. Define Bicycle with its own description() method.
4
Print descriptions of Car and Bicycle
Create instances of Car and Bicycle. Then print the result of calling description() on each instance.
Swift
Hint
Create variables myCar and myBike for the instances. Use print() to show their descriptions.
Practice
(1/5)
1. What is the main purpose of using protocol extensions with default implementations in Swift?
easy
A. To allow protocols to store properties
B. To create new classes that inherit from protocols
C. To enforce that all conforming types must implement every method
D. To provide default method implementations that all conforming types can use
Solution
Step 1: Understand protocol extensions
Protocol extensions allow adding methods or properties with default behavior to protocols.
Step 2: Identify the purpose of default implementations
Default implementations let conforming types use common code without writing it themselves.
Final Answer:
To provide default method implementations that all conforming types can use -> Option D
Quick Check:
Default implementations = shared code for all [OK]
Hint: Default implementations give shared code to all conforming types [OK]
Common Mistakes:
Thinking protocols can store properties
Confusing protocol inheritance with extensions
Believing all methods must be implemented manually
2. Which of the following is the correct syntax to add a default implementation for a protocol method in Swift?
easy
A. extension MyProtocol { func greet() { print(\"Hello\") } }
Hint: Use 'extension ProtocolName' to add default methods [OK]
Common Mistakes:
Trying to put method bodies inside protocol declaration
Using 'extension' inside protocol block
Omitting the 'extension' keyword
3. Consider the code below:
protocol Speaker {
func speak()
}
extension Speaker {
func speak() {
print("Speaking from extension")
}
}
struct Person: Speaker {
func speak() {
print("Person speaking")
}
}
struct Robot: Speaker {}
let p = Person()
p.speak()
let r = Robot()
r.speak()
What is the output when this code runs?
medium
A. Person speaking
Robot speaking
B. Speaking from extension
Speaking from extension
C. Person speaking
Speaking from extension
D. Compilation error
Solution
Step 1: Understand method resolution for protocol extensions
If a conforming type provides its own method, it overrides the default from the extension.
Step 2: Analyze the structs
Person implements speak() so it prints "Person speaking". Robot does not implement it, so uses default "Speaking from extension".
Final Answer:
Person speaking
Speaking from extension -> Option C
Quick Check:
Own method overrides default extension [OK]
Hint: Own method overrides default extension method [OK]
Common Mistakes:
Assuming default is always called
Expecting Robot to cause error
Confusing protocol declaration with implementation
4. The following code tries to add a default implementation for describe() in a protocol extension, but it causes a compile error. What is the mistake?
B. Missing parentheses after method name in extension
C. Extension cannot provide method implementations
D. Missing 'func' keyword in extension
Solution
Step 1: Check method syntax in extension
Method definitions require parentheses even if no parameters are present.
Step 2: Identify the error
The extension method func describe is missing parentheses () after the name.
Final Answer:
Missing parentheses after method name in extension -> Option B
Quick Check:
Method syntax needs () even if empty [OK]
Hint: Always include () after method name in definitions [OK]
Common Mistakes:
Omitting parentheses in method declaration
Thinking protocol methods must have bodies
Believing extensions can't implement methods
5. You want to create a protocol Identifiable with a property id and a default method identify() that prints the id. How would you write the protocol and extension so that conforming types can use the default identify() without extra code?
hard
A. protocol Identifiable { var id: String { get } }\nextension Identifiable { func identify() { print(\"ID: \(id)\") } }
B. protocol Identifiable { func identify() }\nextension Identifiable { var id: String { return \"default\" } }
C. protocol Identifiable { var id: String }\nextension Identifiable { func identify() { print(id) } }
D. protocol Identifiable { var id: String { get set } }\nextension Identifiable { func identify() { print(\"ID: \(id)\") } }"
Solution
Step 1: Define protocol with read-only property
Use var id: String { get } to require an id property that conforming types must provide.
Step 2: Provide default identify() method in extension
Extension adds identify() that prints the id using string interpolation.
Final Answer:
protocol Identifiable { var id: String { get } }\nextension Identifiable { func identify() { print("ID: \(id)") } } -> Option A