Ποια είναι η διαφορά μεταξύ πρωτοκόλλων και κλάσεων όταν πρόκειται για αφηρημένες κλάσεις;
sobes.tech AI
Απάντηση από AI
Ο πρωτόκολλος ορίζει μια σύμβαση — ένα σύνολο απαιτήσεων (μεθόδων, ιδιοτήτων, αρχικοποιητών) που πρέπει να υλοποιήσει ένας τύπος που συμμορφώνεται με αυτό το πρωτόκολλο. Τα πρωτόκολλα δεν έχουν υλοποίηση των περισσότερων απαιτήσεών τους. Δεν είναι δυνατή η δημιουργία στιγμιότυπων πρωτοκόλλου.
Η αφηρημένη κλάση σε γλώσσες διαφορετικές από τη Swift (π.χ. Java) αντιπροσωπεύει μια κλάση που δεν μπορεί να δημιουργηθεί άμεσα. Περιέχει τόσο υλοποιημένες μεθόδους (ή ιδιότητες) όσο και αφηρημένες μεθόδους που πρέπει να υλοποιηθούν στις υποκλάσεις της.
Στη Swift, δεν υπάρχει η έννοια των αφηρημένων κλάσεων με την παραδοσιακή τους έννοια. Η λειτουργικότητα των αφηρημένων κλάσεων επιτυγχάνεται μέσω συνδυασμού πρωτοκόλλων και κλάσεων.
Χρησιμοποιώντας ένα πρωτόκολλο, μπορείτε να ορίσετε μια διεπαφή και στη συνέχεια να δημιουργήσετε μια κανονική κλάση που αντιστοιχεί σε αυτό το πρωτόκολλο και παρέχει υλοποίηση. Μερική υλοποίηση του πρωτοκόλλου μπορεί να παρέχεται μέσω επεκτάσεων (protocol extensions), αλλά αυτό δεν το καθιστά "αφηρημένη κλάση" με την καθαρή έννοια.
| Πρωτόκολλο (Swift) | Αφηρημένη κλάση (παραδοσιακή) | |
|---|---|---|
| Σκοπός | Ορισμός σύμβασης (διεπαφής) | Ορισμός κοινής συμπεριφοράς και δομής με δυνατότητα μερικής υλοποίησης |
| Υλοποίηση | Συνήθως δεν περιέχει υλοποίηση (εκτός από επεκτάσεις) | Μπορεί να περιέχει τόσο υλοποιημένες όσο και αφηρημένες μεθόδους |
| Δημιουργία | Δεν μπορεί να δημιουργηθεί στιγμιότυπο πρωτοκόλλου | Δεν μπορεί να δημιουργηθεί άμεσα στιγμιότυπο αφηρημένης κλάσης |
| Κληρονομικότητα | Συμμόρφωση με πρωτόκολλο (conformance) | Κληρονομικότητα (inheritance) |
| Πολλαπλή κληρονομικότητα | Ο τύπος μπορεί να συμμορφώνεται με πολλά πρωτόκολλα | Η κλάση μπορεί να κληρονομήσει μόνο από μία κλάση (στα περισσότερα γλώσσες) |
| Στη Swift | Είναι η βασική μορφή αφαίρεσης | Δεν υπάρχει άμεσος ισοδύναμος, μιμείται μέσω πρωτοκόλλων και κλάσεων |
Παράδειγμα μίμησης αφηρημένης κλάσης με πρωτόκολλο και κλάση στη Swift:
Πρωτόκολλο που ορίζει απαιτήσεις:
// Πρωτόκολλο, ως σύμβαση
protocol Drawable {
func draw()
var color: String { get set }
}
Κλάση που αντιστοιχεί στο πρωτόκολλο και παρέχει υλοποιήσεις:
// Κλάση που υλοποιεί το πρωτόκολλο
class Circle: Drawable {
var color: String
init(color: String) {
self.color = color
}
func draw() {
print("Ζωγραφίζουμε κύκλο με χρώμα \(color)")
}
}
Επέκταση για παροχή μερικής υλοποίησης από προεπιλογή:
// Επέκταση για παροχή προεπιλεγμένης υλοποίησης (δεν καθιστά το πρωτόκολλο αφηρημένη κλάση)
extension Drawable {
func draw() {
print("Ξεκινάμε να ζωγραφίζουμε κάτι με χρώμα \(color)")
}
}
Έτσι, στη Swift, τα πρωτόκολλα παίζουν κεντρικό ρόλο στην επίτευξη πολυμορφισμού και αφαίρεσης, αντικαθιστώντας την έννοια των αφηρημένων κλάσεων από άλλες γλώσσες.