98
Kapitola 6 Robot Karel a jeho svět, knihovny, balíčky
6.4 Balíčky Vyšší organizační jednotkou programu než třída je balíček (anglicky package). Java umožňuje sdružovat skupiny objektových typů do hierarchicky uspořádaných balíčků. Balíčky mohou obsahovat podbalíčky a tvoří tak stromovou strukturu obdobně jako soubory na disku (viz obrázek 6.2). Balíčky jsou pojmenovávány. Pro jejich názvy platí konvence, že mají obsahovat pouze malá písmena. Na obrázku si můžete všimnout, že balíčky standardní knihovny tuto konvenci dodržují. Balíčky mají ve skutečnosti dva názvy: jednoduchý název (anglicky simple name) je standardní identifikátor a úplný název (v dokumentaci je označován jako fully-qualified name – plně kvalifikovaný název) je složen z úplného názvu jeho rodičovského balíčku následovaného tečkou a jednoduchým názvem.
Kořenový balíček a strom balíčků Jako každý strom i strom balíčků musí mít svůj kořen. Kořenový balíček (občas se setkáte s názvem implicitní balíček nebo defaultní balíček) žádný název nemá (nenechte se zmást tím, že se na obrázku 6.2 zdánlivě jmenuje java.base), což ale nevadí, protože je od verze Obrázek 6.2: 1.3 stejně koncipován jako degenerovaný, takže se prakticky Stromová struktura nepoužívá. Úplný název podbalíčků kořenového balíčku je proto balíčků stejný jako jejich jednoduchý název. Při budování aplikací vzniká několik paralelních stromů balíčků. Samotná standardní knihovna je tvořena několika relativně nezávislými stromy balíčků. Každá používaná knihovna má vlastní strom balíčků. Naše aplikace bude mít také vlastní strom balíčků. Celé toto uspořádání vám může připomínat uspořádání souborů v operačním systému DOS a následně i Windows, kde budou soubory odpovídat jednotlivým třídám, složky balíčkům a disky stromům balíčků. Naštěstí tomu tak není. Jednotlivé kořenové balíčky a na ně navázané stromy sice mohou být umístěny na různých místech, ale virtuální stroj je všechny sloučí do jednoho velkého společného virtuálního stromu se společným kořenovým balíčkem. S tímto sloučeným stromem pak program pracuje.
6.5 Import objektových typů Obdobně jako balíčky, i objektové typy mají dva názvy: jednoduchý název je standardní identifikátor a úplný název objektového typu je tvořen úplným názvem balíčku, v němž je typ umístěn, následovaným tečkou a jednoduchým názvem daného objektového typu. 67_Java_NZ_ZLOM.doc; verze 1.02.8889_2021-11-29_po_13-19
Strana 98 z 400 Ukázka elektronické knihy, UID: KOS507124
6.5 Import objektových typů
99
Obecně musíme objektové typy oslovovat jejich plným názvem. Aby nás však neustálé psaní plných názvů nevyčerpávalo, definovali autoři Javy tři situace, kdy si vystačíme s jednoduchým názvem a překladač za nás plný název doplní:
● Je-li definice typu umístěna ve stejném balíčku jako program, který daný typ oslovuje. To jsme zatím nevyzkoušeli – ověříte si to, až budete vytvářet standardní programy. ● Bez kvalifikace balíčkem můžeme také oslovovat třídy z balíčku java.lang. Z tohoto balíčku pocházely zbylé čtyři třídy, s nimiž jsme doposud pracovali, tj. třídy String, Object, Math a Long. To je také důvod, proč ve výpisech 5.1 na straně 86 a 5.2 na straně 87 nemusíme psát např. java.lang.Math.PI, ale můžeme se omezit na stručnější Math.PI. ● Objektové typy, které explicitně importujeme příkazem import. Tak jsme pracovali např. s třídou Karel, jejíž import byl součástí načítání skriptu s05a_Karel.jsh (viz řádek 10 ve výpisu 6.3 na straně 95). Kdybychom měli všechna oslovování tříd z jiných balíčků zadávat prostřednictvím úplných názvů, asi by nás to začalo brzy obtěžovat. Java proto nabízí možnost daný objektový typ importovat a oslovovat jej poté již pouze jeho jménem bez nutnosti kvalifikace jménem jeho balíčku. Importovat můžete:
● konkrétní objektový typ, ● všechny typy definované v zadaném balíčku. K definici importu datového typu slouží příkaz import, jenž sestává z klíčového slova import, za nímž následují úplný název importovaného datového typu a v běžném programu i povinný ukončovací středník. Takto můžeme importovat vždy jen jeden datový typ. Budeme-li chtít importovat více datových typů, musíme pro import každého z nich použít samostatný příkaz import.
JShell při svém zavádění importuje všechny třídy z několika často používaných balíčků (které to jsou, zjistíte zadáním příkazu /imports). Tyto třídy pak při práci s JShell již nemusíme importovat. Když ale použijete stejnou třídu ve svém programu (tj. ne v interaktivním režimu JShell), importovat ji musíte.
Příklad Pojďme si to hned vyzkoušet. Spustíme znovu JShell a zopakujeme klíčové operace bez pomoci skriptu s05a_Karel.jsh. Postup si můžete prohlédnout ve výpisu 6.4. Na řádku 1 je soubor knihovny zařazen mezi prohledávané. Od této chvíle můžeme používat v něm definované datové typy a pomocné soubory. V JAR-souboru totiž nemusejí být pouze programy, ale mohou tam být i soubory s užitečnými daty. 67_Java_NZ_ZLOM.doc; verze 1.02.8889_2021-11-29_po_13-19
Strana 99 z 400 Ukázka elektronické knihy, UID: KOS507124
100
Kapitola 6 Robot Karel a jeho svět, knihovny, balíčky
Výpis 6.4: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
Načtení knihovny a import potřebných tříd
jshell> /env -class-path ../67_LIB/67_Robot.jar | Setting new options and restoring state. jshell> /reset | Resetting state. jshell> /env | --class-path ..\67_LIB\67_Robot.jar jshell> robot.RobotWindow.newWorld("01234", "56789", "000#0"); $1 ==> RobotWorld{rows=3, cols=5} | created scratch variable $1 : robot.RobotWorld jshell> import robot.Karel; jshell> var k = new Karel(); k ==> Karel_1(row=2, col=0, dir=EAST) | created variable k : Karel jshell> k.step(); k.turnLeft(); jshell>
Příkaz /reset zadaný na řádku 4 zruší všechny doposud vytvořené proměnné a uvede JShell do počátečního stavu, jak dokazuje i reakce na řádku 11 potvrzující, že JShell začal číslovat úryvky znovu od začátku. Nicméně zachovává nastavení dostupných knihoven, což dokazuje reakce na příkaz na řádku 7, z níž se dozvíme, že výše zadaná knihovna zůstává nastavena. Nejprve potřebujeme vytvořit a zobrazit robotí dvorek s definovaným způsobem umístěnými značkami a zdmi. O to je požádána třída RobotWindow z balíčku robot zavoláním její metody newWorld(String...). 20 Protože jsme se na ni chtěli obrátit pouze jednou, tak jsme ji ani neimportovali, na řádku 10 jsme ji oslovili jejím plným názvem a požádali ji o vytvoření okna se zadanou podobou robotího dvorku. Výsledkem operace je vytvoření objektu reprezentujícího svět robotů o třech řádcích a pěti sloupcích a jeho zobrazení v okně. Použitá tovární metoda vrací odkaz na objekt reprezentující vytvořené okno. Protože prozatím nehodláme toto okno využívat, proměnnou jsme nikam neukládali. JShell sice vytvořil pomocnou proměnnou, ale v řádném programu to dělat nemusíte. Na dvorku je třeba vyrobit robota. Protože se na třídu robotů budeme chtít ještě v budoucnu obrátit, tak jsme ji na řádku 14 importovali. Když jsme ji pak na řádku 16 žádali o vytvoření instance, mohli jsme ji díky tomu oslovit jen jejím jednoduchým jménem bez kvalifikace balíčkem.
20
Tři tečky za názvem typu znamenají, že můžeme zadat několik argumentů tohoto typu za sebou. Podrobněji vám o nich povíme v podkapitole 24.5 Metody s proměnným počtem argumentů na straně 362.
67_Java_NZ_ZLOM.doc; verze 1.02.8889_2021-11-29_po_13-19 Ukázka elektronické knihy
Strana 100 z 400