Protocol ist eine Reihe von Anforderungen (Eigenschaften und Methoden), die ein Typ erfüllen muss, der das Protokoll implementiert. In Swift sind Protokolle das zentrale Element der Protocol-Oriented Programming (POP), die Polymorphismus ohne Vererbung ermöglicht. Laut Swift.org (2025) werden Protokolle in 85% der Typen der Swift-Standardbibliothek verwendet. In Objective-C übernimmt @protocol eine ähnliche Rolle, jedoch mit einer Einschränkung — nur für Klassen.
Wichtige Punkte
Protocol in Swift ist eine abstrakte Schnittstelle, die Anforderungen definiert, die ein Typ erfüllen muss. Ein Protokoll kann Eigenschaften (mit Getter/Setter), Methoden (Instanz- und Typmethoden), Initialisierer und Subscripts erfordern. Im Gegensatz zu Klassen können Protokolle von Strukturen, Aufzählungen und Klassen implementiert werden — was Flexibilität bietet, die in rein klassenbasierten Sprachen nicht verfügbar ist.
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)
}
}Die Struktur Circle implementiert das Drawable-Protokoll und stellt die Eigenschaft boundingRect sowie die Methode draw(in:) bereit. Dank des Protokolls kann jede Form, die Drawable implementiert, einheitlich behandelt werden — das ist Polymorphismus ohne Vererbung von einer gemeinsamen Basisklasse.
Protocol-Oriented Programming (POP) ist ein Paradigma, das von Apple auf der WWDC 2015 als Alternative zur klassenbasierten Vererbung eingeführt wurde. In POP sind Protokolle das primäre Abstraktionswerkzeug und Protokollerweiterungen bieten Standardimplementierungen. Dies löst das «Rautenvererbungs»-Problem und ermöglicht die Erweiterung vorhandener Typen ohne Änderung des Quellcodes.
| Aspekt | POP (Protokollorientiert) | OOP (Klassenbasiert) |
|---|---|---|
| Abstraktionseinheit | Protocol | Basisklasse |
| Wiederverwendungsmechanismus | Protocol extension | Vererbung |
| Wertetypen | Unterstützt (struct) | Nur Referenztypen |
| Mehrfachimplementierung | Protocol composition | Mehrfachvererbung (nicht in Swift) |
| Kopplungsrisiko | Niedrig (lose Kopplung) | Hoch (starre Hierarchie) |
Laut dem Apple Swift Blog (2025) machen Strukturen 70% der Typen in modernen Swift-Anwendungen aus. POP ist ein Hauptgrund für diese Verschiebung: Protokolle ermöglichen es Strukturen, polymorphes Verhalten zu erhalten, ohne auf Klassen umzusteigen.
Swift-Protokolle nehmen eine Mittelstellung zwischen Java-Schnittstellen und C++-abstrakten Klassen ein. Sie können Implementierungen enthalten (über Erweiterungen), aber keinen Zustand (gespeicherte Eigenschaften) haben. Lassen Sie uns die Unterschiede in drei Sprachen untersuchen.
| Merkmal | Swift Protocol | Java Interface | C++ Abstract Class |
|---|---|---|---|
| Methodenimplementierung | Ja (extension) | Ja (default methods) | Ja |
| Gespeicherte Eigenschaften | Nein | Nein | Ja |
| Wertetypen | Ja | Nein | Nein |
| Mehrfachimplementierung | Ja | Ja | Ja |
| Initialisierer | Ja (Anforderungen) | Nein | Ja |
Hauptunterschied: Swift Protocol kann Initialisierer und Subscripts erfordern, was in Java Interface nicht verfügbar ist. Ein Protokoll kann jedoch keinen Zustand speichern — dies bleibt die Verantwortung des Typs, der das Protokoll implementiert.
Associated Type (assoziierter Typ) ist ein generischer Typ innerhalb eines Protokolls, der durch den implementierenden Typ konkretisiert wird. Dies ermöglicht die Erstellung typsicherer Protokolle ohne Angabe eines konkreten Datentyps. Assoziierte Typen arbeiten mit Swift-Generics zusammen.
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 {
// Funktionsrumpf
}Container ist ein Protokoll mit associatedtype Item. IntStack implementiert es, indem es typealias Item = Int angibt. Die generische Funktion sum verwendet eine where-Klausel, um nur mit numerischen Containern zu arbeiten. Assoziierte Typen machen Protokolle generisch, ohne die Typsicherheit zu verlieren.
Protocol composition — Kombination mehrerer Protokolle über den &-Operator. Ein Typ, der einer Komposition entspricht, muss alle kombinierten Protokolle implementieren. Dies ersetzt die in Swift nicht vorhandene Mehrfachvererbung und ermöglicht die präzise Spezifikation von Anforderungen an Funktionsparameter.
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), Alter \(entity.age)!")
}
// Protocol extension — Standardimplementierung
extension Named {
func introduce() {
print("Ich heiße \(name)")
}
}Protocol extension bietet Standardmethodenimplementierungen. Ein Typ, der das Protokoll implementiert, kann die Erweiterungsmethode überschreiben — in diesem Fall wird seine eigene Implementierung aufgerufen. Dies ist der Mechanismus, mit dem Swift optionale Methoden ohne @objc implementiert.
@protocol in Objective-C ist der Vorgänger des Swift-Protokolls, jedoch mit erheblichen Einschränkungen. Objective-C-Protokolle sind nur für Klassen verfügbar (nicht für Strukturen oder Aufzählungen) und verwenden dynamische Dispatch über Nachrichtenübergabe. Methoden können @required (Standard) oder @optional sein.
@protocol Loggable
@required
- (void)logMessage: (NSString *)message;
@optional
- (NSString *)logPrefix;
@end
@interface ConsoleLogger : NSObject
@end
@implementation ConsoleLogger
- (void)logMessage: (NSString *)message {
NSLog(@"[LOG] %@", message);
}
@endIm Gegensatz zu Swift unterstützen Objective-C-Protokolle keine assoziierten Typen, Generics, Protokollerweiterungen oder Wertetypen. Sie bleiben ein Mechanismus der klassenbasierten Abstraktion, während Swift Protocol ein vollwertiges Polymorphie-Werkzeug für alle Typen ist.
Häufig gestellte Fragen
Protocol kann keinen Zustand (gespeicherte Eigenschaften) speichern — nur Eigenschaftsanforderungen. Eine abstrakte Klasse kann Datenfelder enthalten. Ein Protokoll kann von Strukturen und Aufzählungen implementiert werden, während eine abstrakte Klasse nur von Klassen abgeleitet werden kann. In Swift sind Protokolle das primäre Abstraktionswerkzeug; Klassen werden seltener verwendet.
POP ist ein Paradigma, bei dem Protokolle und Protokollerweiterungen tiefe Vererbungshierarchien ersetzen. Anstatt einer Basisklasse, von der alle Unterklassen erben, verwendet POP Protokollkomposition mit Standardimplementierungen über Erweiterungen. Dies reduziert die Kopplung und verbessert die Wiederverwendbarkeit von Code.
Ja, Swift-Protokolle unterstützen Vererbung. protocol SerializableDrawable: Drawable, Codable — ein Protokoll, das die Anforderungen von Drawable und Codable kombiniert. Ein Typ, der SerializableDrawable implementiert, muss die Anforderungen aller Protokolle in der Hierarchie erfüllen. Dies unterscheidet sich von der Klassenvererbung — Protokolle haben keinen gemeinsamen Vorfahren.
some (opaque type) garantiert, dass eine Funktion einen bestimmten Typ zurückgibt, der dem Protokoll entspricht. any (existential type) ermöglicht das Speichern jedes Typs, der dem Protokoll entspricht. some wird verwendet, um die Typidentität zu bewahren, any — für heterogene Sammlungen. some erschien in Swift 5.1, any — in Swift 5.7.
Verwenden Sie is zur Überprüfung und as? zum Casten: if let drawable = object as? Drawable { drawable.draw(in: ctx) }. In Objective-C wird conformsToProtocol: verwendet. Swift unterstützt auch is-Überprüfungen für Protokolle ohne assoziierte Typen.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch