Protocol — olyan követelmények (tulajdonságok és metódusok) halmaza, amelyeknek az adott protokollt implementáló típusnak meg kell felelnie. A Swiftben a protokollok a Protocol-Oriented Programming (POP) központi elemei, amelyek lehetővé teszik a polimorfizmust öröklődés nélkül. A Swift.org (2025) adatai szerint a protokollok a Swift szabványos könyvtárának 85%-ában használatosak. Az Objective-C-ben az @protocol hasonló szerepet tölt be, de korlátozással — csak osztályok számára.
Főbb pontok
Protocol a Swiftben — egy absztrakt interfész, amely meghatározza azokat a követelményeket, amelyeknek egy típusnak meg kell felelnie. A protokoll megkövetelhet tulajdonságokat (getter/setterrel), metódusokat (példány- és típus szinten), inicializátorokat és subscriptet. Az osztályokkal ellentétben a protokollok implementálhatók struktúrákkal, felsorolásokkal és osztályokkal — ez olyan rugalmasságot biztosít, amely a tiszta osztályalapú nyelvekben nem elérhető.
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)
}
}A Circle struktúra implementálja a Drawable protokollt, biztosítva a boundingRect tulajdonságot és a draw(in:) metódust. A protokollnak köszönhetően bármely Drawable-t implementáló alakzat egységesen feldolgozható — ez polimorfizmus közös osztályból való öröklődés nélkül.
Protocol-Oriented Programming (POP) — az Apple által a WWDC 2015-ön bemutatott paradigma az osztályalapú öröklődés alternatívájaként. A POP-ban a protokollok az absztrakció fő eszközei, a protokollkiterjesztések (protocol extensions) pedig alapértelmezett implementációt biztosítanak. Ez megoldja a «rombusz-öröklődés» problémáját, és lehetővé teszi a meglévő típusok bővítését a forráskód módosítása nélkül.
| Szempont | POP (Protocol-Oriented) | OOP (Class-based) |
|---|---|---|
| Absztrakció egysége | Protocol | Bázisosztály |
| Újrafelhasználás | Protocol extension | Öröklődés |
| Value types | Támogatott (struct) | Csak reference types |
| Többszörös alkalmazás | Protocol composition | Többszörös öröklődés (nem Swiftben) |
| Kapcsolódás kockázata | Alacsony (laza kapcsolás) | Magas (merev hierarchia) |
Az Apple Swift blog (2025) szerint a struktúrák a modern Swift alkalmazásokban a típusok 70%-át teszik ki. A POP a fő oka ennek a változásnak: a protokollok lehetővé teszik a struktúrák számára, hogy polimorf viselkedést kapjanak anélkül, hogy osztályokra kellene váltaniuk.
A Swift protokollok köztes helyet foglalnak el a Java interfészek és a C++ absztrakt osztályok között. Tartalmazhatnak implementációt (extension révén), de nem rendelkeznek állapottal (tárolt tulajdonságokkal). Nézzük meg a különbségeket három nyelv példáján.
| Jellemző | Swift Protocol | Java Interface | C++ Abstract Class |
|---|---|---|---|
| Metódusok implementációja | Igen (extension) | Igen (default methods) | Igen |
| Tárolt tulajdonságok | Nem | Nem | Igen |
| Value types | Igen | Nem | Nem |
| Többszörös implementáció | Igen | Igen | Igen |
| Inicializátorok | Igen (követelmények) | Nem | Igen |
Fő különbség: a Swift Protocol megkövetelhet inicializátorokat és subscriptet, ami a Java Interface-ben nem elérhető. Ugyanakkor a protokoll nem tárolhat állapotot — ez a protokollt implementáló típus prerogatívája marad.
Associated Type (kapcsolódó típus) — egy általánosított típus a protokollon belül, amelyet az implementáló típus konkretizál. Ez lehetővé teszi típusbiztos protokollok létrehozását anélkül, hogy megadnánk a konkrét adattípust. A kapcsolódó típusok a Swift generics-szel együtt működnek.
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 {
// függvény törzse
}A Container — egy protokoll associatedtype Item-mel. Az IntStack implementálja, megadva a typealias Item = Int értéket. A sum generikus függvény where-megkötést használ, hogy csak numerikus konténerekkel működjön. Az Associated types általánossá teszik a protokollokat a típusbiztonság elvesztése nélkül.
Protocol composition — több protokoll kombinálása & operátorral. A kompozíciónak megfelelő típusnak az összes kombinált protokollt implementálnia kell. Ez helyettesíti a többszörös öröklődést, amely nem létezik a Swiftben, és lehetővé teszi a függvényparaméterekkel szembeni követelmények pontos meghatározását.
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("Helló, \(entity.name), életkor \(entity.age)!")
}
// Protocol extension — alapértelmezett implementáció
extension Named {
func introduce() {
print("A nevem \(name)")
}
}A Protocol extension alapértelmezett implementációt biztosít a metódusokhoz. A protokollt implementáló típus felülírhatja az extension metódust — ebben az esetben a saját implementációja hívódik meg. Ez az a mechanizmus, amellyel a Swift opcionális metódusokat implementál @objc nélkül.
@protocol az Objective-C-ben — a Swift Protocol elődje, de jelentős korlátozásokkal. Az Objective-C protokollok csak osztályok számára érhetők el (nem struktúrák vagy felsorolások számára), és dinamikus diszpécserezést használnak message passing révén. A metódusok lehetnek @required (alapértelmezett) vagy @optional.
@protocol Loggable
@required
- (void)logMessage: (NSString *)message;
@optional
- (NSString *)logPrefix;
@end
@interface ConsoleLogger : NSObject
@end
@implementation ConsoleLogger
- (void)logMessage: (NSString *)message {
NSLog(@"[LOG] %@", message);
}
@endA Swift-től eltérően az Objective-C protokollok nem támogatják az associated types, generics, protocol extensions és value types funkciókat. Az osztályabsztrakció mechanizmusai maradnak, míg a Swift Protocol egy teljes értékű polimorfizmus eszköz minden típus számára.
Gyakran Ismételt Kérdések
Protocol nem tárolhat állapotot (tárolt tulajdonságokat) — csak tulajdonságokra vonatkozó követelményeket. Az abstract class tartalmazhat adatmezőket. A Protocol implementálható struktúrákkal és felsorolásokkal, az abstract class — csak osztályokkal. A Swiftben a protokollok az absztrakció fő eszközei, az osztályokat ritkábban használják.
POP — paradigma, ahol a protokollok és a protokollkiterjesztések felváltják a mély öröklődési hierarchiákat. Ahelyett, hogy egy bázisosztályból származnának az összes alosztályok, a POP protokollkompozíciót használ alapértelmezett implementációkkal extension révén. Ez csökkenti a kapcsolódást és növeli a kód újrafelhasználhatóságát.
Igen, a Swift protokollok támogatják az öröklődést. protocol SerializableDrawable: Drawable, Codable — egy protokoll, amely egyesíti a Drawable és Codable követelményeit. A SerializableDrawable-t implementáló típusnak teljesítenie kell a hierarchiában lévő összes protokoll követelményeit. Ez eltér az osztályöröklődéstől — a protokolloknak nincs közös ősük.
some (opaque type) garantálja, hogy a függvény egy konkrét, a protokollnak megfelelő típust ad vissza. any (existential type) lehetővé teszi bármely, a protokollnak megfelelő típus tárolását. A some a típus identitásának megőrzésére szolgál, az any — heterogén gyűjteményekhez. A some a Swift 5.1-ben, az any a Swift 5.7-ben jelent meg.
Használja az is kulcsszót ellenőrzéshez és az as? kulcsszót konverzióhoz: if let drawable = object as? Drawable { drawable.draw(in: ctx) }. Az Objective-C-ben a conformsToProtocol: használatos. A Swift támogatja az is-ellenőrzést a associated types nélküli protokollokhoz is.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is