====== Třídy v jazyce Java ====== V předcházejícím příkladě jsem vytvořili okno, četli vstupní hodnoty z "check boxu" a editační kolonky a výstupní text jsem přidávaly do větší kolonky v oknu. Nyní se podíváme na základy programovacího jazyka Java, nejprve si zkusíme "konzolovou" aplikaci. Podobně jako v prvním příkladu vytvoříme nový projekt: Menu **File**, **New Project**, **Java Ant / Java Application** Projekt pojmenuji **Experiment**. \\ Třída se bude také jmenovat Experiment (s velkým písmenem jak je u tříd v Javě zvykem, ale překladač to nekontroluje)). \\ Balíček (package) se bude jmenovat **experiment** (s malým písmenem jak je zvykem u balíčků). \\ Vznikne hlavní třída experiment.Experiment, kterou tentokrát použijeme. package experiment; public class Experiment { private boolean b; private char c = 'Č'; private short i; private int j; private long k; private float x; private double y; public static int cnt; public Experiment () { System.out.println ("Vytvarim novou instanci tridy Experiment"); java.io.PrintStream out = System.out; i ++; // zvetsime nestatickou promennou, v kazde instanci je samostatna promenna i out.print ("b="); out.println (b); out.print ("c="); out.print (c); out.print (", vnitrni hodnota c="); out.println ((int) c); out.print ("i="); out.println (i); out.print ("j="); out.println (j); out.print ("k="); out.println (k); out.print ("x="); out.println (x); out.print ("y="); out.println (y); cnt ++; // zvetsime statickou promennou, promenna cnt je jen jedna v celem programu out.print ("cnt="); out.println (cnt); out.println (); } public static void main (String[] args) { Experiment e = new Experiment (); Experiment t = new Experiment (); } } [[https://gitlab.fjfi.cvut.cz/culikzde/java-priklady/-/blob/258d88be/Experiment/src/experiment/Experiment.java|odkaz na zdrojové texty odpovídající právě popsanému textu na gitlab.fjfi.cvut.cz]] Vytvarim novou instanci tridy Experiment b=false c=Č, vnitrni hodnota c=268 i=1 j=0 k=0 x=0.0 y=0.0 cnt=1 Vytvarim novou instanci tridy Experiment b=false c=Č, vnitrni hodnota c=268 i=1 j=0 k=0 x=0.0 y=0.0 cnt=2 ===== Proměnné a jejich typy ===== Ve třídě Experiment deklarujeme několik proměnných. Klíčová slova ovlivnňující přístupová práva * **private** deklarace jsou přístupné jen uvnitř třídy * **protected** deklarace jsou přístupné ve své třídě a v odvozených třídách * **public** deklarace jsou dostupné i z vnějšku * pokud není private, protected ani public uvedeno je deklarace přístupná ze svého balíčku ( nebo jsme klíčové slovo zapomněli napsat :-) ) Proměnné objektového typu obsahují jen __odkaz__ (ukazatel) na objekt nebo **null**. Neobjektové typy se nazývají __primitivní__ a proměnné obsahují přímo hodnoty daného typu a překladač pro ně vyhradí předem známý počet bytů. \\ Primitivní typy mají v Javě definovanou velikost nezávislou na implementaci, např. int 4 byty, long 8 bytu. \\ Číselné typy jsou se znaménkem, jen char je bez znaménka * **short** 16-bitová celá čísla ( od -215 do 215-1 ) * **int** 32-bitová celá čísla ( asi od -2.109 do 2.109 ) * **long** 64-bitová celá čísla ( asi od -8.1018 do 8.1018 ) * **float** 32-bitová racionální čísla (24 bitů mantisy, tj. asi 7 desítkových číslic, rozsah hodnot asi do 1038 ) * **double** 64-bitová racionální čísla (52 bitů mantisy, tj. asi 15 desítkových číslic, asi do 10300 ) * **bool** logické hodnoty **true** a **false**, ukládaná jako celý jeden byte * **char** 16-bitové znaky ( jediný typ bez znaménka, hodnoty od 0 do 65535 představují znaky z abecedy [[https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane|Unicode]] ) ( Typ **char** pracuje s 216 znaky, dnešní Unicode umožňuje až 17.216 znaků. Zbývajících 220 znaků se obvykle kóduje dvěma 16-bitovými znaky pomocí [[https://en.wikipedia.org/wiki/UTF-16|UTF-16]]. K tomu je v 16-bitovém kódování vyhrazeno 2048 [[https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Surrogates|zvláštních znaků]]. V 16-bitovém kódování také naleznete 6400 znaků, které si může uživatel sám [[https://en.wikipedia.org/wiki/Private_Use_Area|definovat]]. ) Proměnné deklarované uvnitř třídy se automaticky __inicializují__ na **null**, **false** nebo **0**. ( Lokální proměnné nikoliv.) V naší třídě je deklarováno několik proměnných, které budou v každé instanci naší třídy private boolean b; private char c = 'Č'; private short i; private int j; private long k; private float x; private double y; ===== Statické proměnné a metody ===== Oproti tomu statické proměnné budou v celém programu jen v jednom exempláři, nezávisle na tom kolik instancí vyvtvoříme. public static int cnt; Proměnná **cnt** je automaticky inicializovaná na nulu. \\ A v konstruktoru je zvětšena o jedna. \\ Na výstupu z našeho programu vidíme, že pokud vzniknou ve funkci main dvě instance naší třídy, proměnná cnt obshauje dvojku. Můžete porovnat s proměnnou **i**, která není statická, v každé instanci je jiná samostatná proměnná **i** a při zvětšení o jedna obě proměnné i obsahují pouze jedničku. Statická proměnná existuje již před vytvořením první instance, můžeme k ní přistupovat pomocí jména třídy tečky a jména proměnné, zkuste např. public static void main (String[] args) { Experiment.cnt = 10; Experiment e = new Experiment (); Experiment t = new Experiment (); } Statické proměnné jsou obdobou globálních proměnných jen jsou umístěny uvnitř třídy. Statické metody jsou obdobou globálních funkcí. \\ Jsou použitelné ještě dříve než vznikne první instance dané třídy. \\ Ale mohou pracovat jen se statickými proměnnými a statickými metodami. V Javě na nejvyšší úrovni kromě balíčků mohou být jen třídy. \\ Pokud třída v Javě obsahuje statickou metodu s identifikátorem **main**, používá se tato metoda ke spuštění třídy. \\ (Známe z NetBeans, např. pravou myší "Run File") V našem programu statická metoda main postupně vytváří dvě instance naší třídy. A při vzniku instance je zavolány konstruktor. ===== Spuštění programu z příkazové řádky ===== Z příkazové řádky spustíme program/třídu příkazem java jméno_balíčku.jméno_třídy případné řádkové parametry Vstoupíme do adresáře, kde se nalézá podadresář jmenující se stejně jako náš balíček **experiment** ve kterém je přeložený soubor **Experiment.class** \\ Např. do .../NetBeansProjects/jméno_projektu/build/classes /usr/lib/jvm/jre-11/bin/java experiment.Experiment Na řádce není nikde použit identifikátor main ani přípony souborů .java nebo .class \\ Pokud máme nainstalováno několik verzí javy, tak vybrereme příkaz java z adresáře podle verze použité při kompilaci. ===== Textový výstup ===== V Javě je standardní balíček **java.lang** (tj. v balíčku java je "podbalíček" lang), který je standardně přítomen a nemusíme ho importovat. V balíčku java.lang je třída **System** a v ní statická proměnná **out** umožňující výstup na konzoli. System.out.println ("Vytvarim novou instanci tridy Experiment"); Abych nemusel neustále psát System.out, vytvořím si svoji lokální proměnnou **out** typu **PrintStream** z balíčku java.io a do této proměnné zkopírují odkaz na "standardní výstup". java.io.PrintStream out = System.out; Pro výstup používám metodu **print**, která je několikrát deklarována pro různé typy parametrů (__přetížená__ funkce, overloaded). \\ Např. jednou s parametrem typu String a podruhé s parametrem typu int. out.print ("cnt="); out.print (cnt); Funkce **println** bez parametrů ukončí řádek, **println** s parametrem vytiskne parametr a potom ukončí řádek. \\ Více parametrů zmíněné metody nedovolují.