Defining Protocols
Part of the Object Oriented Programming section of Coddy's Swift journey. Lesson 27 of 57.
A protocol lists requirements (methods and properties) without implementing them. A type conforms to the protocol by providing every requirement, and then it can be used wherever the protocol is expected:
protocol Describable {
func describe() -> String
}
struct Book: Describable {
let title: String
func describe() -> String { "Book: \(title)" }
}
print(Book(title: "Dune").describe())Output:
Book: DuneUnlike inheritance, a protocol works for structs, classes and enums alike, and a type can conform to many protocols. The protocol only says what a type can do; each type decides how:
protocol Describable {
func describe() -> String
}
struct Point: Describable {
var x = 0, y = 0
func describe() -> String { "(\(x), \(y))" }
}
enum Level: Describable {
case low, high
func describe() -> String { self == .low ? "low" : "high" }
}
print(Point(x: 1, y: 2).describe())
print(Level.high.describe())Output:
(1, 2)
highProperty requirements state the type and whether the property is read-only ({ get }) or also writable ({ get set }). A { get } requirement can be met by a stored or a computed property:
protocol Named {
var name: String { get }
}
struct User: Named {
let name: String
}
struct Planet: Named {
var number: Int
var name: String { "Planet \(number)" }
}
print(User(name: "ada").name)
print(Planet(number: 3).name)Output:
ada
Planet 3If a type claims to conform but misses a requirement, it does not compile. The compiler checks every conformance, so code that uses the protocol can rely on it:
protocol Priced {
var price: Int { get }
func discounted(by percent: Int) -> Int
}
// struct Ticket: Priced { var price = 10 }
// error: type 'Ticket' does not conform to protocol 'Priced'Challenge
EasyDeclare a protocol Shape with a read-only property name (String) and a method area() returning Double. Make the structs Rectangle (width, height) and Circle (radius, using 3.0 for π to keep the numbers simple) conform to it, with the names rectangle and circle.
The supplied code reads lines r,3,4 or c,2, creates the matching shape and prints rectangle: 12.0.
Your code goes in Shape.swift, Rectangle.swift and Circle.swift. main.swift holds the supplied input/output code and cannot be edited.
Try it yourself
// Supplied input/output code: keep it as it is
var input: [String] = []
while let line = readLine() { input.append(line) }
for line in input {
let p = line.split(separator: ",").map(String.init)
if p[0] == "r" {
let s = Rectangle(width: Double(p[1])!, height: Double(p[2])!)
print("\(s.name): \(s.area())")
} else {
let s = Circle(radius: Double(p[1])!)
print("\(s.name): \(s.area())")
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Classes and Objects
Working With FilesDefining ClassesMethods and selfInitializersClasses Are ReferencesRecap - Library Card4Encapsulation
Access ControlRead-Only From OutsideGuarding StateFailable InitializersRecap - Bank Account7Polymorphism and Generics
PolymorphismType CastingGeneric FunctionsGeneric TypesRecap - Shape Calculator5Inheritance
SubclassesOverriding MethodsInitializers and superfinal and HierarchiesRecap - Employee Hierarchy11Project: Library Management
Books and MembersBorrowing Books3Properties in Depth
Computed PropertiesProperty ObserversStatic MembersEnums with MethodsRecap - Temperature Log6Protocols
Defining ProtocolsConforming TypesProtocol ExtensionsProtocols as TypesRecap - Payment SystemPractice on your own: Swift playground