Protocol, protokolü benimseyen türün karşılaması gereken gereksinimler (özellikler ve yöntemler) kümesidir. Swift'te protokoller, kalıtım olmadan çok biçimlilik sağlayan Protocol-Oriented Programming'in (POP) merkezi öğesidir. Swift.org'a (2025) göre protokoller, Swift standart kütüphanesindeki türlerin %85'inde kullanılır. Objective-C'de @protocol benzer bir rol oynar, ancak bir sınırlamayla — yalnızca sınıflar için.
Önemli Noktalar
Protocol Swift'te protokol, bir türün karşılaması gereken gereksinimleri tanımlayan soyut bir arayüzdür. Bir protokol, özellikler (getter/setter ile), yöntemler (örnek ve tür), başlatıcılar ve alt simgeler gerektirebilir. Sınıfların aksine, protokoller yapılar, numaralandırmalar ve sınıflar tarafından benimsenebilir — tamamen sınıf tabanlı dillerde bulunmayan esneklik sağlar.
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 yapısı Drawable protokolünü benimseyerek boundingRect özelliğini ve draw(in:) yöntemini sağlar. Protokol sayesinde Drawable'ı uygulayan herhangi bir şekil tek biçimde işlenebilir — bu, ortak bir temel sınıftan kalıtım almadan çok biçimliliktir.
Protocol-Oriented Programming (POP), Apple tarafından WWDC 2015'te sınıf tabanlı kalıtıma alternatif olarak tanıtılan bir paradigmadır. POP'da protokoller ana soyutlama aracıdır ve protokol uzantıları varsayılan uygulamalar sağlar. Bu, «elmas kalıtım» sorununu çözer ve kaynak kodunu değiştirmeden mevcut türleri genişletmeye olanak tanır.
| Yön | POP (Protokol Odaklı) | OOP (Sınıf Tabanlı) |
|---|---|---|
| Soyutlama birimi | Protocol | Temel sınıf |
| Yeniden kullanım mekanizması | Protocol extension | Kalıtım |
| Değer türleri | Desteklenir (struct) | Yalnızca referans türleri |
| Çoklu benimseme | Protocol composition | Çoklu kalıtım (Swift'te yok) |
| Bağlantı riski | Düşük (gevşek bağlantı) | Yüksek (katı hiyerarşi) |
Apple Swift bloguna (2025) göre, modern Swift uygulamalarında türlerin %70'i yapılardır. POP bu değişimin temel nedenidir: protokoller, yapıların sınıflara geçmeden çok biçimli davranış elde etmesini sağlar.
Swift protokolleri Java arayüzleri ile C++ soyut sınıfları arasında bir orta konumda yer alır. Uygulama içerebilirler (uzantılar yoluyla) ancak durum (saklanan özellikler) barındıramazlar. Üç dil arasındaki farkları inceleyelim.
| Özellik | Swift Protocol | Java Interface | C++ Abstract Class |
|---|---|---|---|
| Yöntem uygulaması | Evet (extension) | Evet (default methods) | Evet |
| Saklanan özellikler | Hayır | Hayır | Evet |
| Değer türleri | Evet | Hayır | Hayır |
| Çoklu uygulama | Evet | Evet | Evet |
| Başlatıcılar | Evet (gereksinimler) | Hayır | Evet |
Temel fark: Swift Protocol başlatıcılar ve alt simgeler gerektirebilir, bu Java Interface'de mevcut değildir. Ancak bir protokol durum saklayamaz — bu, protokolü benimseyen türün sorumluluğundadır.
Associated Type (ilişkili tür), bir protokol içinde benimseyen tür tarafından somutlaştırılan genel bir türdür. Bu, somut bir veri türü belirtmeden tür güvenli protokoller oluşturmayı sağlar. İlişkili türler, Swift generics ile birlikte çalışır.
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 {
// işlev gövdesi
}Container, associatedtype Item ile bir protokoldür. IntStack, typealias Item = Int belirterek onu uygular. Genel işlev sum, yalnızca sayısal kapsayıcılarla çalışmak için where yan tümcesini kullanır. İlişkili türler, tür güvenliğini kaybetmeden protokolleri genel hale getirir.
Protocol composition — & operatörüyle birden çok protokolün birleştirilmesi. Bir bileşime uyan tür, birleştirilmiş tüm protokolleri uygulamalıdır. Bu, Swift'te bulunmayan çoklu kalıtımın yerini alır ve işlev parametrelerinin gereksinimlerinin hassas şekilde belirtilmesine olanak tanır.
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("Merhaba, \(entity.name), yaş \(entity.age)!")
}
// Protocol extension — varsayılan uygulama
extension Named {
func introduce() {
print("Benim adım \(name)")
}
}Protocol extension varsayılan yöntem uygulamaları sağlar. Protokolü benimseyen bir tür, uzantı yöntemini geçersiz kılabilir — bu durumda kendi uygulaması çağrılır. Swift'in @objc olmadan isteğe bağlı yöntemleri uyguladığı mekanizma budur.
@protocol Objective-C'de @protocol, Swift Protocol'ün öncülüdür ancak önemli sınırlamalarla birlikte gelir. Objective-C protokolleri yalnızca sınıflar için kullanılabilir (yapılar veya numaralandırmalar için değil) ve mesaj iletimi yoluyla dinamik dağıtım kullanır. Yöntemler @required (varsayılan) veya @optional olabilir.
@protocol Loggable
@required
- (void)logMessage: (NSString *)message;
@optional
- (NSString *)logPrefix;
@end
@interface ConsoleLogger : NSObject
@end
@implementation ConsoleLogger
- (void)logMessage: (NSString *)message {
NSLog(@"[LOG] %@", message);
}
@endSwift'in aksine, Objective-C protokolleri ilişkili türleri, generics'i, protokol uzantılarını veya değer türlerini desteklemez. Bunlar sınıf tabanlı soyutlama mekanizması olarak kalırken, Swift Protocol tüm türler için tam özellikli bir çok biçimlilik aracıdır.
Sıkça Sorulan Sorular
Protocol durum (saklanan özellikler) depolayamaz — yalnızca özellik gereksinimleri. Soyut sınıf veri alanları içerebilir. Protokol, yapılar ve numaralandırmalar tarafından benimsenebilirken, soyut sınıf yalnızca sınıflar tarafından alt sınıflanabilir. Swift'te protokoller ana soyutlama aracıdır; sınıflar daha az sıklıkla kullanılır.
POP, protokollerin ve protokol uzantılarının derin kalıtım hiyerarşilerini değiştirdiği bir paradigmadır. Tüm alt sınıfların kalıtım aldığı bir temel sınıf yerine POP, uzantı yoluyla varsayılan uygulamalarla protokol bileşimini kullanır. Bu, bağlantıyı azaltır ve kod yeniden kullanılabilirliğini artırır.
Evet, Swift protokolleri kalıtımı destekler. protocol SerializableDrawable: Drawable, Codable — Drawable ve Codable gereksinimlerini birleştiren bir protokol. SerializableDrawable'ı benimseyen bir tür, hiyerarşideki tüm protokollerin gereksinimlerini karşılamalıdır. Bu, sınıf kalıtımından farklıdır — protokollerin ortak bir atası yoktur.
some (opak tür), bir işlevin protokole uyan belirli bir tür döndürmesini garanti eder. any (varoluşsal tür), protokole uyan herhangi bir türü depolamaya izin verir. some tür kimliğini korumak için kullanılır, any — heterojen koleksiyonlar için. some Swift 5.1'de, any Swift 5.7'de ortaya çıktı.
Kontrol için is ve dönüştürme için as? kullanın: if let drawable = object as? Drawable { drawable.draw(in: ctx) }. Objective-C'de conformsToProtocol: kullanılır. Swift, ilişkili türleri olmayan protokoller için is kontrolünü de destekler.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun