Protocol — скуп захтева (својстава и метода) које тип који имплементира дати протокол мора да испуни. У Swift-у, протоколи су централни елемент Protocol-Oriented Programming (POP), омогућавајући полиморфизам без наслеђивања. Према подацима Swift.org (2025), протоколи се користе у 85% типова стандардне библиотеке Swift-а. У Objective-C-у, @protocol има сличну улогу, али са ограничењем — само за класе.
Главно
Protocol у Swift-у — апстрактни интерфејс који дефинише захтеве које тип мора да испуни. Протокол може захтевати својства (са getter/setter-ом), методе (инстанце и типа), иницијализаторе и subscript. За разлику од класа, протоколи могу бити имплементирани од стране структура, енумерација и класа — то пружа флексибилност недоступну у чисто класним језицима.
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)
}
}Структура Circle имплементира протокол Drawable, обезбеђујући својство boundingRect и метод draw(in:). Захваљујући протоколу, било која фигура која имплементира Drawable може се обрађивати јединствено — то је полиморфизам без наслеђивања од заједничке базне класе.
Protocol-Oriented Programming (POP) — парадигма коју је Apple предложио на WWDC 2015 као алтернатива класном наслеђивању. У POP-у, протоколи су главни алат апстракције, а проширења протокола (protocol extensions) пружају имплементацију подразумевано. Ово решава проблем „ромбоидног наслеђивања“ и омогућава проширење постојећих типова без модификације изворног кода.
| Аспект | POP (Protocol-Oriented) | OOP (Class-based) |
|---|---|---|
| Јединица апстракције | Protocol | Базнa класа |
| Поновна употреба | Protocol extension | Наслеђивање |
| Value types | Подржани (struct) | Само reference types |
| Вишеструка примена | Protocol composition | Вишеструко наслеђивање (не у Swift-у) |
| Ризик спрезања | Низак (слаба спрегнутост) | Висок (крута хијерархија) |
Према подацима Apple Swift blog (2025), структуре чине 70% типова у савременим Swift апликацијама. POP је кључни разлог овог помака: протоколи омогућавају структурама да добију полиморфно понашање без преласка на класе.
Swift протоколи заузимају средњу позицију између Java интерфејса и C++ апстрактних класа. Могу садржати имплементацију (кроз extension), али немају стање (складиштена својства). Размотрићемо разлике на примеру три језика.
| Карактеристика | Swift Protocol | Java Interface | C++ Abstract Class |
|---|---|---|---|
| Имплементација метода | Да (extension) | Да (default methods) | Да |
| Складиштена својства | Не | Не | Да |
| Value types | Да | Не | Не |
| Вишеструка имплементација | Да | Да | Да |
| Иницијализатори | Да (захтеви) | Не | Да |
Кључна разлика: Swift Protocol може захтевати иницијализаторе и subscript, што није доступно у Java Interface. Протокол не може складиштити стање — то остаје prerogativa типа који имплементира протокол.
Associated Type (повезани тип) — уопштени тип унутар протокола који се конкретизује од стране типа који имплементира. Ово омогућава стварање type-safe протокола без навођења конкретног типа података. Повезани типови раде у пару са 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 {
// тело функције
}Container — протокол са associatedtype Item. IntStack га имплементира, наводећи typealias Item = Int. Генеричка функција sum користи where-ограничење за рад само са нумеричким контејнерима. Associated types чине протоколе уопштеним без губитка type-safe.
Protocol composition — комбиновање више протокола кроз оператор &. Тип који одговара композицији мора имплементирати све обједињене протоколе. Ово замењује вишеструко наслеђивање, одсутно у Swift-у, и омогућава прецизно специфицирање захтева за параметре функције.
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("Здраво, \(entity.name), старост \(entity.age)!")
}
// Protocol extension — имплементација подразумевано
extension Named {
func introduce() {
print("Зовем се \(name)")
}
}Protocol extension пружа имплементацију метода подразумевано. Тип који имплементира протокол може прегазити метод extension-а — у том случају се позива његова сопствена имплементација. Ово је механизам помоћу којег Swift имплементира опционе методе без @objc.
@protocol у Objective-C-у — претходник Swift Protocol-а, али са значајним ограничењима. Objective-C протоколи су доступни само за класе (не за структуре или енумерације) и користе динамичку диспечеру кроз message passing. Методе могу бити @required (подразумевано) или @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);
}
@endЗа разлику од Swift-а, Objective-C протоколи не подржавају associated types, generics, protocol extensions и value types. Они остају механизам класне апстракције, док је Swift Protocol пуноправни алат полиморфизма за све типове.
Често постављана питања
Protocol не може складиштити стање (складиштена својства) — само захтеве за својствима. Abstract class може садржати поља са подацима. Protocol може бити имплементиран од стране структура и енумерација, abstract class — само од класа. У Swift-у, протоколи су главни алат апстракције, класе се користе ређе.
POP — парадигма где протоколи и проширења протокола замењују дубоке хијерархије наслеђивања. Уместо базне класе од које наслеђују све подкласе, POP користи композицију протокола са имплементацијама подразумевано кроз extension. Ово смањује спрегнутост и повећава поновну употребу кода.
Да, Swift протоколи подржавају наслеђивање. protocol SerializableDrawable: Drawable, Codable — протокол који обједињује захтеве Drawable и Codable. Тип који имплементира SerializableDrawable мора испунити захтеве свих протокола у хијерархији. Ово се разликује од class наслеђивања — протоколи немају заједничког претка.
some (opaque type) гарантује да функција враћа један конкретан тип који одговара протоколу. any (existential type) омогућава складиштење било ког типа који одговара протоколу. some се користи за очување идентитета типа, any — за хетерогене колекције. some се појавио у Swift 5.1, any — у Swift 5.7.
Користите is за проверу и as? за претварање: if let drawable = object as? Drawable { drawable.draw(in: ctx) }. У Objective-C-у се користи conformsToProtocol:. Swift такође подржава is-проверу за протоколе без associated types.
Закључак
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође