Protocol — is een set vereisten (eigenschappen en methoden) waaraan het type dat het protocol implementeert moet voldoen. In Swift zijn protocollen het centrale element van Protocol-Oriented Programming (POP), waarmee polymorfisme zonder overerving mogelijk is. Volgens Swift.org (2025) worden protocollen gebruikt in 85% van de typen van de Swift-standaardbibliotheek. In Objective-C vervult @protocol een vergelijkbare rol, maar met een beperking — alleen voor klassen.
Belangrijkste punten
Protocol in Swift — is een abstracte interface die de vereisten definieert waaraan een type moet voldoen. Een protocol kan eigenschappen (met getter/setter), methoden (van instantie en type), initializers en subscript vereisen. In tegenstelling tot klassen kunnen protocollen worden geïmplementeerd door structuren, opsommingen en klassen — dit biedt flexibiliteit die niet beschikbaar is in puur klasse-gebaseerde talen.
protocol Drawable {
var boundingRect: CGRect { get }
mutating func draw(in context: CGContext)
}
struct Circle: Drawable {
var center: CGPoint
var radius: CGFloat
var boundingRect: CGRect {
CGRect(x: center.x - radius, y: center.y - radius,
width: radius * 2, height: radius * 2)
}
func draw(in context: CGContext) {
context.addEllipse(in: boundingRect)
}
}De structuur Circle implementeert het protocol Drawable, met de eigenschap boundingRect en de methode draw(in:). Dankzij het protocol kan elke figuur die Drawable implementeert uniform worden verwerkt — dit is polymorfisme zonder overerving van een gemeenschappelijke basisklasse.
Protocol-Oriented Programming (POP) — een paradigma dat door Apple op WWDC 2015 werd geïntroduceerd als alternatief voor klasse-overerving. In POP zijn protocollen het belangrijkste abstractie-instrument en bieden protocoluitbreidingen (protocol extensions) standaardimplementaties. Dit lost het probleem van «ruitvormige overerving» op en maakt het mogelijk bestaande types uit te breiden zonder de broncode aan te passen.
| Aspect | POP (Protocol-Oriented) | OOP (Class-based) |
|---|---|---|
| Abstractie-eenheid | Protocol | Basisklasse |
| Hergebruik | Protocol extension | Overerving |
| Value types | Ondersteund (struct) | Alleen reference types |
| Meervoudige toepassing | Protocol composition | Meervoudige overerving (niet in Swift) |
| Koppelingsrisico | Laag (losse koppeling) | Hoog (stijve hiërarchie) |
Volgens de Apple Swift blog (2025) vormen structuren 70% van de typen in moderne Swift-applicaties. POP is de belangrijkste reden voor deze verschuiving: protocollen stellen structuren in staat polymorf gedrag te krijgen zonder over te stappen op klassen.
Swift-protocollen nemen een tussenpositie in tussen Java-interfaces en C++-abstracte klassen. Ze kunnen implementatie bevatten (via extension), maar hebben geen status (opgeslagen eigenschappen). We bekijken de verschillen aan de hand van drie talen.
| Kenmerk | Swift Protocol | Java Interface | C++ Abstract Class |
|---|---|---|---|
| Implementatie van methoden | Ja (extension) | Ja (default methods) | Ja |
| Opgeslagen eigenschappen | Nee | Nee | Ja |
| Value types | Ja | Nee | Nee |
| Meervoudige implementatie | Ja | Ja | Ja |
| Initializers | Ja (vereisten) | Nee | Ja |
Het belangrijkste verschil: Swift Protocol kan initializers en subscript vereisen, wat niet beschikbaar is in Java Interface. Het protocol kan echter geen status opslaan — dit blijft de verantwoordelijkheid van het type dat het protocol implementeert.
Associated Type (geassocieerd type) — een gegeneraliseerd type binnen het protocol dat wordt geconcretiseerd door het implementerende type. Hiermee kunnen type-veilige protocollen worden gemaakt zonder een specifiek gegevenstype op te geven. Geassocieerde types werken samen met Swift-generics.
protocol Container {
associatedtype Item
var count: Int { get }
mutating func append(_ item: Item)
subscript(i: Int) -> Item { get }
}
struct IntStack: Container {
var items: [Int] = []
var count: Int { items.count }
typealias Item = Int
mutating func append(_ item: Int) {
items.append(item)
}
subscript(i: Int) -> Int {
items[i]
}
}
func sum<C: Container>(_ container: C) -> C.Item where C.Item: Numeric {
// functielichaam
}Container — een protocol met associatedtype Item. IntStack implementeert het en specificeert typealias Item = Int. De generische functie sum gebruikt een where-beperking om alleen met numerieke containers te werken. Associated types maken protocollen gegeneraliseerd zonder verlies van type-veiligheid.
Protocol composition — het combineren van meerdere protocollen via de &-operator. Een type dat aan de compositie voldoet, moet alle gecombineerde protocollen implementeren. Dit vervangt meervoudige overerving, die niet bestaat in Swift, en maakt het mogelijk vereisten voor functieparameters nauwkeurig te specificeren.
protocol Named { var name: String { get } }
protocol Aged { var age: Int { get } }
struct Person: Named, Aged {
let name: String
let age: Int
}
func greet(_ entity: Named & Aged) {
print("Hallo, \(entity.name), leeftijd \(entity.age)!")
}
// Protocol extension — standaardimplementatie
extension Named {
func introduce() {
print("Mijn naam is \(name)")
}
}Protocol extension biedt een standaardimplementatie van methoden. Het type dat het protocol implementeert, kan de extension-methode overschrijven — in dat geval wordt zijn eigen implementatie aangeroepen. Dit is het mechanisme waarmee Swift optionele methoden implementeert zonder @objc.
@protocol in Objective-C — de voorloper van Swift Protocol, maar met aanzienlijke beperkingen. Objective-C-protocollen zijn alleen beschikbaar voor klassen (niet voor structuren of opsommingen) en gebruiken dynamische dispatch via message passing. Methoden kunnen @required (standaard) of @optional zijn.
@protocol Loggable
@required
- (void)logMessage: (NSString *)message;
@optional
- (NSString *)logPrefix;
@end
@interface ConsoleLogger : NSObject
@end
@implementation ConsoleLogger
- (void)logMessage: (NSString *)message {
NSLog(@"[LOG] %@", message);
}
@endIn tegenstelling tot Swift ondersteunen Objective-C-protocollen geen associated types, generics, protocol extensions en value types. Ze blijven een mechanisme voor klasse-abstractie, terwijl Swift Protocol een volwaardig polymorfisme-instrument is voor alle typen.
Veelgestelde vragen
Protocol kan geen status opslaan (opgeslagen eigenschappen) — alleen vereisten voor eigenschappen. Abstract class kan velden met gegevens bevatten. Protocol kan worden geïmplementeerd door structuren en opsommingen, abstract class — alleen door klassen. In Swift zijn protocollen het belangrijkste abstractie-instrument, klassen worden minder vaak gebruikt.
POP — een paradigma waarin protocollen en protocoluitbreidingen diepe overervingshiërarchieën vervangen. In plaats van een basisklasse waarvan alle subklassen overerven, gebruikt POP compositie van protocollen met standaardimplementaties via extension. Dit vermindert koppeling en verhoogt herbruikbaarheid van code.
Ja, Swift-protocollen ondersteunen overerving. protocol SerializableDrawable: Drawable, Codable — een protocol dat de vereisten van Drawable en Codable combineert. Een type dat SerializableDrawable implementeert, moet voldoen aan de vereisten van alle protocollen in de hiërarchie. Dit verschilt van klasse-overerving — protocollen hebben geen gemeenschappelijke voorouder.
some (opaque type) garandeert dat een functie één concreet type retourneert dat aan het protocol voldoet. any (existential type) maakt het mogelijk elk type op te slaan dat aan het protocol voldoet. some wordt gebruikt om de identiteit van het type te behouden, any — voor heterogene collecties. some verscheen in Swift 5.1, any — in Swift 5.7.
Gebruik is voor controle en as? voor conversie: if let drawable = object as? Drawable { drawable.draw(in: ctx) }. In Objective-C wordt conformsToProtocol: gebruikt. Swift ondersteunt ook is-controle voor protocollen zonder associated types.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook