IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

11. diel - Protokoly (rozhranie) vo Swift

V minulej lekcii, Vlastnosti vo Swift , sme si precvičili prácu s vlastnosťami. Dnes to vo Swift tutoriálu bude opäť trochu teoretické, objavíme ďalšie topí objektovo orientovaného programovania, uvedieme si totiž tzv. Rozhranie, ktoré Swift implementuje ako protokoly.

Rozhranie

Rozhraním objektu sa myslí to, ako je objekt viditeľný zvonku. Už vieme, že objekt obsahuje nejaké metódy, tie môžu byť privátne alebo verejné. Rozhranie objektu tvorí práve jeho verejné metódy, je to spôsob, akým s určitým typom objektu môžeme komunikovať. Už sme niekoľkokrát mohli vidieť aké verejné metódy naša trieda ponúka, napr. U nášho bojovníka do arény. Trieda Bojovnik mala nasledujúce verejné metódy:

  • func utoc(souper: Bojovnik)
  • func branSe(uder: Int)
  • func nazivu() -> Bool
  • func nastavZpravu(zprava: String)
  • func vratPosledniZpravu() -> String
  • func grafickyZivot() -> String

Pokiaľ si do nejakej premennej uložíme inštanciu bojovníka, môžeme na ňu volať metódy ako utoc() alebo branSe(). To stále nie je nič nové, že?

My si však rozhrania môžeme deklarovať zvlášť a to podobným spôsobom ako napr. Triedu. Hovoríme, že sme vytvorili protokol. A tento protokol definujúci rozhranie potom použijeme ako dátový typ.

Všetko si vyskúšame, ale na niečom jednoduchším, než je bojovník. Vytvorme si nový projekt, konzolovú aplikáciu a nazvime ho Protokoly. Pridáme si nejakú jednoduchú triedu. Pretože by sa podľa môjho názoru mala teórie vysvetľovať na niečom odľahčujúcim, vytvoríme vtáka. Bude vedieť pípať, dýchať a jednoduchú recykláciu. Pridajme si triedu Ptak, bude vyzerať takto:

class Ptak {

    func pipni() {
        print("♫ ♫ ♫")
    }

    func dychej() {
        print("Dýchám...")
    }

    func klovni() {
        print("Klov, klov!")
    }

}

Trieda je naozaj triviálne. Prejdime do main.swift a vytvorme si inštanciu vtáka:

let ptak = Ptak()

Teraz napíšeme ptak. a necháme Xcode, aby nám zobrazilo metódy na triede (možno tiež vyvolať stlačením Ctrl + Space):

Metódy na inštanciu vo Swift - Objektovo orientované programovanie vo Swift

Vidíme, čo na vtákovi môžeme všetko volať. Sú tam samozrejme tie 3 metódy, čo sme v triede implementovali (plus ďalšie, ktoré majú objekty v základe).

Teraz vtákovi vytvoríme protokol. Využijeme na to kľúčového slova protocol. Názvy protokolov často končí anglickú koncovkou -able, takže môžeme mať Printable, Convertible, Renderable pod. Z protokolu je vlastne vidieť, akú funkcionalitu ponúka. Napr. Renderable môže znamenať, že pôjde vyrenderovať, čiže zobraziť ako súčasť UI.

Pre zjednodušenie náš protokol pomenujeme PtakProtokol a pokojne ho môžeme pre zjednodušenie umiestniť do súboru Ptak.swift nad triedu Ptak. Tiež si definujeme požadované metódy:

protocol PtakProtokol {

    func pipni()

    func dychej()

}

Modifikátor public neuvádzame, pretože protokol obsahuje vždy len verejné metódy (inak by nemal zmysel, udáva, ako s objektom zvonku pracovať).

Vráťme sa do main.swift a zmeňme riadok s premennou ptak tak, aby už nebola typu Ptak, ale PtakProtokol:

let ptak : PtakProtokol = Ptak()

Kódom vyššie hovoríme, že v premennej typu PtakProtokol očakávame objekt, ktorý obsahuje tie metódy, čo sú v protokole. Xcode nám vynadá, pretože trieda Ptak zatiaľ protokol PtakProtokol neobsahuje, aj keď potrebné metódy má, nevie, že protokol poskytuje. Presunieme sa do triedy Ptak a nastavíme jej, že implementuje protokol PtakProtokol. Robí sa to rovnako, ako keď trieda od inej dedí:

class Ptak: PtakProtokol {
    // . . .

Keď sa teraz vrátime do main.swift, riadok s premennou typu PtakProtokol je už v poriadku. Trieda Ptak korektne implementuje protokol PtakProtokol a jej inštancie môže byť do premennej tohto typu uložená.

Skúsme teraz vymazať z triedy nejakú metódu, ktorú protokol udáva, napr. pipni(). Xcode nás upozorní, že implementácia nie je kompletný. Vráťme ju zas späť.

Opäť pridáme riadok ptak., Xcode nám ponúkne nasledujúce metódy:

Metódy na protokole vo Swift - Objektovo orientované programovanie vo Swift

Vidíme, že na inštanciu môžeme teraz volať iba metódy, ktoré poskytuje protokol. To preto, že premenná ptak je už typu PtakProtokol, nie Ptak. Metóda klovni() úplne chýba.

K čomu je to dobré? Výhod a využitie je viac, na prvý sme už prišli. Pomocou protokolov dokážeme zjednodušiť protokol nejakého zložitého objektu a vystaviť len tú časť, ktorá sa nám v tú dobu hodí.

Ešte dodám, že nemôžeme vytvoriť inštanciu z protokolu, tento kód nebude fungovať:

// tento kód nebude fungovat
let ptak : PtakProtokol = PtakProtokol()

Viacnásobná dedičnosť

Swift (rovnako ako väčšina programovacích jazykov) nepodporuje viacnásobnú dedičnosť. Nemôžeme teda jednu triedu oddědit z niekoľkých iných tried. Je to hlavne z toho dôvodu, že môže vzniknúť problém kolízie názvov metód v rôznych triedach, z ktorých dedíme. Viacnásobná dedičnosť sa často obchádza práve cez protocol, pretože tých môžeme v triede implementovať koľko chceme. Umožňuje nám to s inštanciou potom pracovať určitým spôsobom a vôbec nás nezaujíma, akého typu objekt v skutočnosti je a čo všetko navyše obsahuje.

Pridajme si k projektu protocol JesterProtokol. Bude to protokol jaštera. Ten bude vedieť tiež dýchať a ešte sa plaziť. Pre zjednodušenie môžete protokol vytvoriť v aktuálnom súbore Ptak.swift alebo si založiť nový Swift súbor:

protocol JesterProtokol {
    func plazSe()
    func dychej()
}

Vyskúšajme si "viacnásobnú dedičnosť", presnejšie implementáciu viacerých protokolov v jednej triede. Urobme si ptakoještěr. Pridajme k projektu triedu PtakoJester.swift. Bude implementovať protokoly PtakProtokol a JesterProtokol:

class PtakoJester: PtakProtokol, JesterProtokol {

}

Keď teraz klikneme v tomto kóde pravým tlačidlom na PtakoJester v definícii triedy, môžeme v kontextovom menu zvoliť Refactor -> Add Missing Protocol Requierements a Xcode nám vygeneruje potrebné metódy, takže ich stačí implementovať.

Automatická implementácia Swift protokolov v Xcode - Objektovo orientované programovanie vo Swift

Po implementácii oboch protokolov vyzerá kód triedy takto, <#code#> je v Xcode špeciálny placeholder pre kód:

class PtakoJester: PtakProtokol, JesterProtokol {

    func pipni() {
        <#code#>
    }

    func dychej() {
        <#code#>
    }

    func plazSe() {
        <#code#>
    }

    func dychej() {
        <#code#>
    }

}

Xcode z nejakého dôvodu vygenerovalo metódu dychej() dvakrát, ak sa vám to tiež stane, stačí jednu z nich zmazať.

Metódy doimplementujeme:

func pipni() {
    print("♫ ♫♫ ♫ ♫ ♫♫")
}

func dychej() {
    print("Dýchám ...")
}

func plazSe() {
    print("Plazím se...")
}

A presuňme sa do main.swift a vytvorme si inštanciu ptakoještěr:

let ptakojester = PtakoJester()

Uistite sa, že má metódy z vtáka i jaštera. Mne sa bohužiaľ zbláznilo Xcode a v nápovede ukazovalo 3x metódu dychej(). Krátky výlet na Google ukázal, že to nie je ojedinelý problém ... Bohužiaľ, na druhú stranu nejde o nič kritického.

V budúcej lekcii, Pretypovania a hierarchie objektov vo Swift , budeme pokračovať v podobnom duchu. Protokoly ešte neopustíme a naučíme sa ďalšie pokročilé techniky objektovo orientovaného programovania.


 

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 11x (18.42 kB)

 

Predchádzajúci článok
Vlastnosti vo Swift
Všetky články v sekcii
Objektovo orientované programovanie vo Swift
Preskočiť článok
(neodporúčame)
Pretypovania a hierarchie objektov vo Swift
Článok pre vás napísal Filip Němeček
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje vývoji iOS aplikací (občas macOS)
Aktivity