Mis vahe on protokollide ja klasside vahel, kui jutt käib abstraktsetest klassidest?
sobes.tech AI
Vastus AI-lt
Protokoll määratleb lepingut — nõuete kogumi (meetodid, omadused, initsialiseerijad), mida peab täitma selle protokolliga vastav tüüp. Protokollidel puudub enamik nende nõuete rakendusi. Protokolli eksemplare luua ei saa.
Abstraktne klass teistes keeltes (näiteks Java) on klass, mida ei saa otse instantsida. See sisaldab nii rakendatud meetodeid (või omadusi) kui ka abstraktseid meetodeid, mida tuleb rakendada selle alamklassides.
Swiftis ei ole traditsioonilise mõistena abstraktseid klasse. Abstraktsete klasside funktsionaalsus saavutatakse protokollide ja klasside kombinatsiooniga.
Protokolli kasutades saab määratleda liidese ning seejärel luua tavalise klassi, mis vastab sellele protokollile ja pakub rakendust. Osaline protokolli rakendus võib olla olemas protokolli laienduste (protocol extensions) kaudu, kuid see ei tee protokolli "abstraktseks klassiks" puhtal kujul.
| Protokoll (Swift) | Abstraktne klass (traditsiooniline) | |
|---|---|---|
| Eesmärk | Lepingu (liidese) määratlemine | Üldise käitumise ja struktuuri määratlemine võimalusega osaliselt rakendada |
| Rakendamine | Tavaliselt ei sisalda rakendust (välja arvatud laiendused) | Võib sisaldada nii rakendatud kui ka abstraktseid meetodeid |
| Eksemplaride loomine | Ei saa luua protokolli eksemplari | Ei saa otse luua abstraktse klassi eksemplari |
| Pärimine | Vastavus protokollile (conformance) | Pärimine (inheritance) |
| Mitmekesisus | Tüüp võib vastata mitmele protokollile | Klass võib pärida ainult ühe klassi (enamikus keeltes) |
| Swift | Peamine abstraktsiooni vorm | Otse ekvivalenti ei ole, seda imiteeritakse protokollide ja klassidega |
Näide, kuidas imiteerida abstraktset klassi protokolli ja klassi abil Swiftis:
Protokoll, mis määratleb abstraktsed nõuded:
// Protokoll, kui leping
protocol Drawable {
func draw()
var color: String { get set }
}
Klass, mis vastab protokollile ja pakub rakendust:
// Klass, mis rakendab protokolli
class Circle: Drawable {
var color: String
init(color: String) {
self.color = color
}
func draw() {
print("Joonistame ringi värviga \(color)")
}
}
Laiendus, mis pakub osalist vaikimisi rakendust:
// Laiendus, mis pakub vaikimisi rakendust (ei tee protokollist "abstraktset klassi")
extension Drawable {
func draw() {
print("Alustame midagi värviga \(color) joonistama")
}
}
Seega mängivad Swiftis protokollid võtmerolli polümorfismi ja abstraktsiooni saavutamisel, asendades teiste keelte abstraktsete klasside kontseptsiooni.