Protocol — este un set de cerințe (proprietăți și metode) pe care trebuie să le îndeplinească tipul care implementează protocolul respectiv. În Swift, protocoalele sunt elementul central al Protocol-Oriented Programming (POP), permițând polimorfism fără moștenire. Conform datelor Swift.org (2025), protocoalele sunt utilizate în 85% din tipurile bibliotecii standard Swift. În Objective-C, @protocol joacă un rol similar, dar cu limitarea — doar pentru clase.
Principalele idei
Protocol în Swift — este o interfață abstractă care definește cerințele pe care un tip trebuie să le îndeplinească. Protocolul poate cere proprietăți (cu getter/setter), metode (de instanță și de tip), inițializatori și subscript. Spre deosebire de clase, protocoalele pot fi implementate de structuri, enumerări și clase — oferind flexibilitate indisponibilă în limbile pur bazate pe clase.
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)
}
}Structura Circle implementează protocolul Drawable, furnizând proprietatea boundingRect și metoda draw(in:). Datorită protocolului, orice figură care implementează Drawable poate fi procesată uniform — acesta este polimorfism fără moștenirea unei clase de bază comune.
Protocol-Oriented Programming (POP) — paradigma propusă de Apple la WWDC 2015 ca alternativă la moștenirea bazată pe clase. În POP, protocoalele sunt principalul instrument de abstractizare, iar extensiile de protocol (protocol extensions) oferă implementare implicită. Aceasta rezolvă problema „moștenirii romboidale” și permite extinderea tipurilor existente fără modificarea codului sursă.
| Aspect | POP (Protocol-Oriented) | OOP (Class-based) |
|---|---|---|
| Unitatea de abstractizare | Protocol | Clasa de bază |
| Reutilizare | Protocol extension | Moștenire |
| Value types | Suportate (struct) | Doar reference types |
| Aplicare multiplă | Protocol composition | Moștenire multiplă (nu în Swift) |
| Risc de cuplare | Scăzut (cuplare slabă) | Ridicat (ierarhie rigidă) |
Conform blogului Apple Swift (2025), structurile reprezintă 70% din tipurile în aplicațiile Swift moderne. POP este motivul principal al acestei schimbări: protocoalele permit structurilor să obțină comportament polimorfic fără a trece la clase.
Protocoalele Swift ocupă o poziție intermediară între interfețele Java și clasele abstracte C++. Ele pot conține implementare (prin extension), dar nu au stare (proprietăți stocate). Să analizăm diferențele pe exemplul a trei limbaje.
| Caracteristică | Swift Protocol | Java Interface | C++ Abstract Class |
|---|---|---|---|
| Implementarea metodelor | Da (extension) | Da (default methods) | Da |
| Proprietăți stocate | Nu | Nu | Da |
| Value types | Da | Nu | Nu |
| Implementare multiplă | Da | Da | Da |
| Inițializatori | Da (cerințe) | Nu | Da |
Diferența cheie: Swift Protocol poate cere inițializatori și subscript, ceea ce nu este disponibil în Java Interface. În același timp, protocolul nu poate starea stare — aceasta rămâne prerogativa tipului care implementează protocolul.
Associated Type (tip asociat) — un tip generalizat în interiorul protocolului, care este concretizat de tipul implementator. Acest lucru permite crearea de protocoale type-safe fără a specifica un tip de date concret. Tipurile asociate funcționează împreună cu genericele Swift.
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 {
// corpul funcției
}Container — un protocol cu associatedtype Item. IntStack îl implementează, specificând typealias Item = Int. Funcția generică sum folosește where-constrângerea pentru a lucra doar cu containere numerice. Associated types fac protocoalele generalizate fără pierderea type-safety.
Protocol composition — combinarea mai multor protocoale prin operatorul &. Tipul care corespunde compoziției trebuie să implementeze toate protocoalele combinate. Aceasta înlocuiește moștenirea multiplă, absentă în Swift, și permite specificarea precisă a cerințelor pentru parametrii funcției.
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("Salut, \(entity.name), vârsta \(entity.age)!")
}
// Protocol extension — implementare implicită
extension Named {
func introduce() {
print("Mă numesc \(name)")
}
}Protocol extension oferă implementarea implicită a metodelor. Tipul care implementează protocolul poate suprascrie metoda extension — în acest caz, propria sa implementare este apelată. Acesta este mecanismul prin care Swift implementează metode opționale fără @objc.
@protocol în Objective-C — predecesorul Swift Protocol, dar cu limitări semnificative. Protocoalele Objective-C sunt disponibile doar pentru clase (nu pentru structuri sau enumerări) și folosesc expedierea dinamică prin message passing. Metodele pot fi @required (implicit) sau @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);
}
@endSpre deosebire de Swift, protocoalele Objective-C nu suportă associated types, generics, protocol extensions și value types. Ele rămân un mecanism de abstractizare pe clase, în timp ce Swift Protocol este un instrument complet de polimorfism pentru toate tipurile.
Întrebări frecvente
Protocol nu poate starea stare (proprietăți stocate) — doar cerințe pentru proprietăți. Abstract class poate conține câmpuri cu date. Protocol poate fi implementat de structuri și enumerări, abstract class — doar de clase. În Swift, protocoalele sunt principalul instrument de abstractizare, clasele sunt utilizate mai rar.
POP — paradigma în care protocoalele și extensiile de protocol înlocuiesc ierarhiile profunde de moștenire. În locul unei clase de bază de care moștenesc toate subclasele, POP folosește compoziția de protocoale cu implementări implicite prin extension. Aceasta reduce cuplarea și crește reutilizarea codului.
Da, protocoalele Swift suportă moștenirea. protocol SerializableDrawable: Drawable, Codable — un protocol care combină cerințele Drawable și Codable. Tipul care implementează SerializableDrawable trebuie să îndeplinească cerințele tuturor protocoalelor din ierarhie. Aceasta diferă de moștenirea claselor — protocoalele nu au un strămoș comun.
some (opaque type) garantează că funcția returnează un tip concret care corespunde protocolului. any (existential type) permite stocarea oricărui tip care corespunde protocolului. some este folosit pentru păstrarea identității tipului, any — pentru colecții eterogene. some a apărut în Swift 5.1, any — în Swift 5.7.
Folosiți is pentru verificare și as? pentru conversie: if let drawable = object as? Drawable { drawable.draw(in: ctx) }. În Objective-C se folosește conformsToProtocol:. Swift suportă și verificarea is pentru protocoale fără associated types.
Concluzii
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și