Lekce 2 - První objektová aplikace ve Swift
Minulá lekce, Úvod do objektově orientovaného programování ve Swift, nás uvedla do objektově orientovaného programování. Již víme, že objekty mají atributy a metody. Také víme, že k vytvoření objektu vytvoříme nejprve třídu. Ta je vzorem, podle kterého následně tvoříme její instance.
Na začátku kurzu se základními konstrukcemi jazyka Swift jsme si vytvořili program Hello world. Udělejme si nyní podobný program jako úvod do objektově orientovaného programování. Naprogramujme si Hello object world!
Založme si v Xcode novou konzolovou aplikaci (Command Line Tool) tak, jak jsme to dělali doposud. V Project navigator nalevo (výpis souboru projektu) klikneme pravým tlačítkem myši na složku našeho projektu a vybereme "New File...".
V zobrazeném dialogu vybereme možnost "Swift File" a pokračujeme
kliknutím na "Next". Nový soubor pojmenujeme Zdravic.swift
a
potvrdíme. Název třídy píšeme vždy velbloudí notací bez mezer a na
rozdíl od proměnných má každé slovo velké první písmeno, tedy i první.
Název je samozřejmě také bez diakritiky, tu v programu používáme max.
uvnitř textových řetězců, nikoli v identifikátorech.
Máme před sebou nový zdrojový soubor. V zakomentované části můžete
vidět např. informace o datu vytvoření a nechybí
import Foundation
pro import základní části jazyka Swift.
Třídu si musíme deklarovat sami, není to ale nic těžkého:
class Zdravic {
}
Podle této třídy později vytvoříme objekt zdravic
, který
nás bude umět pozdravit. Vidíme, že se na program již díváme úplně
jinak, za každou akci je zodpovědný nějaký objekt, nestačí pouze něco
"nabušit" do souboru main.swift
. V našem případě vám to
může přijít zbytečné, u složitějších aplikací si to budete
pochvalovat
Ve Swift nejsou třídy zařazené do balíčků nebo jmenných prostorů,
jako je tomu v některých ostatních programovacích jazycích. Místo toho je
základní jednotkou Swift soubor, přičemž není nutné mít všechen kód
uvnitř nějaké třídy. Prakticky se tak často vytváří např. soubor
Constants.swift
, kde jsou pouze String
konstanty
deklarované pomocí let
, aby byly na jednom místě a nemohli jste
si omylem způsobit problémy překlepem.
Druhou "jednotkou" v jazyce Swift jsou moduly. Apple je definuje jako "single
unit of distribution". Modul je zkrátka něco, co v sobě obsahuje zamýšlenou
funkcionalitu a dá se použít v různých programech. Náš nový projekt je
vlastně také modul sám o sobě, ale nedává smysl ho využít v jiných
aplikacích. Stejně tak Foundation
je modul, nebo později
UIKit
, který se importuje jako základ v iOS aplikacích místo
Foundation
(protože Foundation
obsahuje).
Nyní si do třídy Zdravic
přidáme metodu
pozdrav()
, bude veřejně viditelná a nebude mít žádnou
návratovou hodnotu ani parametry.
Deklarace metody ve Swift je tedy následující:
[modifikátor přístupu] func [jmenoMetody]([parametry]) -> [návratový typ]
Před metodou nemusí být tzv. modifikátor přístupu, jako výchozí
používá Swift modifikátor internal
, který znamená přístup v
rámci modulu (takže v našem případě celá konzolová aplikace). Dále bude
následovat samotný název metody, metody píšeme stejně jako třídy
velbloudí notací s malým poč. písmenem. Závorka s parametry je povinná,
my ji necháme prázdnou, protože metoda žádné parametry mít nebude. Do
těla metody zapíšeme kód pro výpis na konzoli.
Naše třída bude nyní vypadat takto:
class Zdravic { func pozdrav() { print("Hello object world!") } }
Zde jsme prozatím skončili, přejdeme do main.swift
.
Nyní si v souboru main vytvoříme instanci třídy
Zdravic
. Bude to tedy ten objekt zdravic
, se kterým
budeme pracovat. Objekty se ukládají do proměnných, název třídy slouží
jako datový typ. Instance má zpravidla název třídy, jen má první písmeno
malé. Deklarujme si proměnnou a následně v ní založme novou instanci
třídy Zdravic
:
let zdravic : Zdravic
zdravic = Zdravic()
První řádek říká: "Chci proměnnou zdravic
, ve které bude
instance třídy Zdravic
". S proměnnými jsme vlastně již takto
pracovali. Na prvním řádku provádíme pouze deklaraci, takže lze využít
let
. Po prvním přiřazení už nebude možné do proměnné
zdravic
přiřadit novou instanci.
Na druhém řádku založíme novou instanci třídy Zdravic
pomocí kulatých závorek. Tuto instanci přiřadíme do naší proměnné.
Při vytvoření nové instance se zavolá tzv. konstruktor. To je speciální metoda na třídě, proto při vytvoření instance píšeme ty prázdné závorky, jelikož voláme tuto "vytvářecí" metodu. Konstruktor zpravidla obsahuje nějakou inicializaci vnitřního stavu instance (např. dosadí výchozí hodnoty do proměnných). My jsme v kódu žádný konstruktor nedeklarovali, Swift si proto vytvořil tzv. implicitní bezparametrický konstruktor. Vytvoření instance objektu je tedy podobné volání metody. Celý zápis můžeme samozřejmě zkrátit na:
let zdravic = Zdravic()
Jelikož v proměnné nyní máme opravdu instanci třídy
Zdravic
, můžeme instanci nechat pozdravit. Zavoláme na ni metodu
pozdrav()
a to jako zdravic.pozdrav()
. Kód soubor
main.swift
bude tedy nyní vypadat následovně:
{SWIFT} let zdravic : Zdravic zdravic = Zdravic() zdravic.pozdrav() {/SWIFT}
{SWIFT} class Zdravic { func pozdrav() { print("Hello object world!") } } {/SWIFT}
Program spustíme.
Hello object world!
Máme tedy svou první objektovou aplikaci!
Dejme nyní naší metodě pozdrav()
parametr
jmeno
, aby dokázala pozdravit konkrétního uživatele:
func pozdrav(jmeno: String) { print("Ahoj uživateli \(jmeno)!") }
Vidíme, že syntaxe parametru metody je stejná, jako syntaxe proměnné.
Kdybychom chtěli parametrů více, oddělujeme je čárkou. Upravíme nyní
náš soubor main.swift
:
{SWIFT} let zdravic : Zdravic zdravic = Zdravic() zdravic.pozdrav(jmeno: "Karel") zdravic.pozdrav(jmeno: "Petr") {/SWIFT}
{SWIFT} class Zdravic { func pozdrav(jmeno: String) { print("Ahoj uživateli \(jmeno)!") } } {/SWIFT}
Náš kód je nyní v metodě a my ho můžeme jednoduše pomocí parametrů
volat znovu s různými parametry. Nemusíme 2x opisovat "Ahoj uživateli...".
Kód budeme odteď dělit logicky do metod. Odlišností od řady jazyků je ve
Swift přítomnost názvů parametrů při volání metody. V našem případě
jmeno
, bez něj nebude program fungovat. Pokud bychom chtěli dát
názvy parametrů pryč z volání, využijeme v deklaraci metody _
před názvem parametru. Při volání ho poté psát nebudeme.
func pozdrav(_ jmeno: String) { print("Ahoj uživateli \(jmeno)!") }
Volání metody by vypadalo takto:
zdravic.pozdrav("Karel")
Výstup:
Ahoj uživateli Karel! Ahoj uživateli Petr!
Třídě přidáme nějakou vlastnost, nabízí se text
, kde
bude uložen text pozdravu. Vlastnosti se definují stejně, jako proměnné.
Jako u metod platí, že před ně píšeme modifikátor přístupu, bez něj je
Swift opět bere jako internal
, což nám vyhovuje. Upravme naši
třídu:
class Zdravic { var text: String = "" func pozdrav(_ jmeno: String) { print("\(text) \(jmeno)!") } }
Vlastnost text
jsme si nastavili na prázdný
String
, protože jinak bychom museli řešit Optional
nebo vlastní konstruktor. Text nyní musíme pochopitelně nastavit vytvořené
instanci v main.swift
:
{SWIFT} let zdravic = Zdravic() zdravic.text = "Ahoj uživateli" zdravic.pozdrav("Karel") zdravic.pozdrav("Petr") zdravic.text = "Vítám tě tu programátore" zdravic.pozdrav("Richard") {/SWIFT}
{SWIFT} class Zdravic { var text: String = "" func pozdrav(_ jmeno: String) { print("\(text) \(jmeno)!") } } {/SWIFT}
Výstup:
Ahoj uživateli Karel! Ahoj uživateli Petr! Vítám tě tu programátore Richard!
Vzhledem k objektovému návrhu není nejvhodnější, aby si každý objekt
ovlivňoval vstup a výstup, jak se mu zachce. Pochopitelně narážím na naše
vypisování do konzole. Každý objekt by měl mít určitou kompetenci a tu by
neměl překračovat. Pověřme náš objekt pouze sestavením pozdravu a jeho
výpis si zpracujeme již mimo, v našem případě v souboru
main.swift
. Výhodou takto navrženého objektu je vysoká
univerzálnost a znovupoužitelnost. Objekt doposud umí jen psát do konzole,
my ho však přizpůsobíme tak, aby daná metoda text pouze vracela a bylo na
jeho příjemci, jak s ním naloží. Takto můžeme pozdravy ukládat do
souborů, psát na webové stránky nebo dále zpracovávat.
Jelikož chceme, aby metoda vracela hodnotu a to String
,
přidáme návratový typ String
. K návratu hodnoty použijeme
příkaz return
. Return metodu ukončí a
navrátí hodnotu, jakýkoli kód v těle metody po return
se již
neprovede! Upravme obě třídy:
Metoda pozdrav()
v Zdravic.swift
:
func pozdrav(_ jmeno: String) -> String { return "\(text) \(jmeno)!" }
Upravený kód v main.swift
:
{SWIFT} let zdravic = Zdravic() zdravic.text = "Ahoj uživateli" print(zdravic.pozdrav("Karel")) print(zdravic.pozdrav("Petr")) zdravic.text = "Vítám tě tu programátore" print(zdravic.pozdrav("Richard")) {/SWIFT}
{SWIFT} class Zdravic { var text: String = "" func pozdrav(_ jmeno: String) -> String { return "\(text) \(jmeno)!" } } {/SWIFT}
Nyní je náš kód dle dobrých praktik.
A jsme u konce. Námi napsaný program má již nějakou úroveň, i když vlastně nic nedělá. Za úkol máte předělat si naši konzolovou kalkulačku do objektů.
V následujícím cvičení, Řešené úlohy k 1.-2. lekci OOP ve Swift, si procvičíme nabyté zkušenosti z předchozích lekcí.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 29x (17.9 kB)
Aplikace je včetně zdrojových kódů v jazyce Swift