class and protocol are orthogonal concepts. A protocol cuts across the class tree and joins one or more classes with a disparate ancestry.
Perhaps put more simply:
- "class" defines what an object is.
- "protocol" defines a behavior the object has.
So you have a class Car:
class Car {
var bodyStyle : String
}
and a class Color:
class Color {
var red : Int
var green : Int
var blue : Int
}
Now, more or less obviously Colors and Cars are completely unrelated, however, let's suppose I want to be able to easily convert either one to Strings, so I can debug with:
print(Car(...))
or
print(Color(...))
For exactly this purpose, the Swift language defines the protocol CustomStringConvertible
so we can then declare the a Car can be printed by using that protocol:
extension Car : CustomStringConvertible {
var description : String { get { return "Car: \(bodyStyle)" } }
}
and a Color as well:
extension Color : CustomStringConvertible {
var description : String { get { return "Color: \(red) \(green) \(blue)" } }
}
So where before I would've needed one print method for each class, now I only need one print method that looks something like:
func print(data:CustomStringConvertible) {
let string = data.description
... bunch of code to actually print the line
}
This is possible because declaring that a class implements a protocol is a promise that I can use the methods from the protocol, knowing that they're implemented and (presumably) do what's expected.