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 | Βασική κλάση |
| Επαναχρησιμοποίηση | Protocol extension | Κληρονομικότητα |
| Value types | Υποστηρίζονται (struct) | Μόνο reference types |
| Πολλαπλή εφαρμογή | Protocol composition | Πολλαπλή κληρονομικότητα (όχι στη Swift) |
| Κίνδυνος σύζευξης | Χαμηλός (χαλαρή σύζευξη) | Υψηλός (άκαμπτη ιεραρχία) |
Σύμφωνα με το ιστολόγιο Apple Swift (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. Ωστόσο, το πρωτόκολλο δεν μπορεί να αποθηκεύει κατάσταση — αυτό παραμένει προνόμιο του τύπου που υλοποιεί το πρωτόκολλο.
Associated Type (συσχετισμένος τύπος) — ένας γενικευμένος τύπος μέσα στο πρωτόκολλο που συγκεκριμενοποιείται από τον υλοποιούντα τύπο. Αυτό επιτρέπει τη δημιουργία type-safe πρωτοκόλλων χωρίς να καθορίζεται ένας συγκεκριμένος τύπος δεδομένων. Οι συσχετισμένοι τύποι λειτουργούν μαζί με τα generics της 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-safety.
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 πρέπει να ικανοποιεί τις απαιτήσεις όλων των πρωτοκόλλων στην ιεραρχία. Αυτό διαφέρει από την κληρονομικότητα κλάσεων — τα πρωτόκολλα δεν έχουν κοινό πρόγονο.
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. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης