Specializovan² t²denφk o v²poΦetnφ technice o Internetu (CW 44/97) Programovßnφ v jazyce Java (3. dφl)
David ètrupl
D∞d∞nφ PouhΘ vytvß°enφ t°φd a objekt∙ by nep°inßÜelo prakticky nic novΘho oproti standardnφmu (procedurßlnφmu) zp∙sobu programovßnφ. D∙le₧it²m a Φasto pou₧φvan²m rysem skuteΦn∞ objektov²ch jazyk∙ je pou₧itφ tzv. d∞diΦnosti. D∞diΦnost je mo₧nost vytvß°et tzv. potomky ji₧ existujφcφch t°φd. Ka₧d² potomek je novß t°φda, kterß mß vÜechny vlastnosti svΘho p°edka a m∙₧e k nim p°idat jeÜt∞ n∞kterΘ dalÜφ. Nap°. mßme-li definovßn typ Zakaznik, m∙₧eme chtφt vytvo°it nov² druh zßkaznφka, kter² bude mφt vlastnosti p∙vodnφho typu -- ale krom∞ toho jeÜt∞ umo₧nφ p°idat prom∞nnou, kterß urΦuje slevu, p°i°azenou dobrΘmu zßkaznφkovi:
class DobryZakaznik extends Zakaznik {
KlφΦovΘ slovo extends v definici t°φdy znamenß rozÜφ°enφ p∙vodnφho typu -- v naÜem p°φkladu vytvo°enφ novΘho potomka t°φdy Zakaznik. Potomek p°itom d∞dφ vÜechny vlastnosti p∙vodnφ t°φdy. P°idßvßnφ vlastnostφ je pouze jeden aspekt vytvß°enφ rozÜφ°enφ ji₧ existujφcφch t°φd. Druhou, mo₧nß d∙le₧it∞jÜφ mo₧nostφ je tzv. p°epsat n∞kterΘ metody vyskytujφcφ se ve t°φd∞ p°edka. Nap°. chceme-li zm∞nit zp∙sob placenφ tak, aby odpovφdal ud∞lenΘ slev∞, m∙₧eme napsat novou definici t°φdy DobryZakaznik:
class DobryZakaznik extends Zakaznik {
Novß definice metody zaplatil zakr²vß p∙vodnφ definici uvedenou ve t°φd∞ Zakaznik. Aby doÜlo k zakrytφ starΘ metody metodou novou, musφ mφt ob∞ stejnou deklaraci, tj. musφ se stejn∞ jmenovat, mφt stejnΘ parametry a stejn² typ nßvratovΘ hodnoty. K Φemu by mohlo b²t takovΘ zakrytφ dobrΘ? P°edstavte si, ₧e mßte na jinΘm mφst∞ programu metodu pracujφcφ n∞jak²m komplexnφm zp∙sobem se zßkaznφky:
void pracujSeZakaznikem(Zakaznik x) { Tuto metodu m∙₧eme zavolat s parametrem typu Zakaznik nebo s libovoln²m potomkem t°φdy Zakaznik -- nap°. jako parametr m∙₧e b²t uveden n∞jak² dobr² zßkaznφk. V prom∞nnΘ x, kterß je typu Zakaznik, se m∙₧e vyskytovat odkaz na libovolnΘho potomka uvedenΘ t°φdy. TΘto vlastnosti pou₧itφ odkaz∙ na objekty se n∞kdy °φkß polymorfismus neboli mnohotvarost. V dob∞, kdy pφÜeme metodu pracujSeZakaznikem, toti₧ nevφme, jakΘho p°esn∞ druhu bude objekt dosazen² jako parametr do prom∞nnΘ x (Zakaznik nebo DobryZakaznik). V jazyce Java existuje jedna t°φda, kterß mß tak trochu v²sadnφ postavenφ. Tato t°φda se jmenuje Object (p°esn∞ji java.lang.Object -- je toti₧ ulo₧ena v balφku java.lang). Pokud p°i definovßnφ novΘ t°φdy neuvedeme rodiΦovskou t°φdu, je implicitn∞ dosazena t°φda Object. To mß za nßsledek, ₧e vÜechny t°φdy jsou bu∩ p°φm²mi, nebo nep°φm²mi potomky t°φdy Object (viz obrßzek D∞d∞nφ od t°φdy Object). To mß n∞kterΘ v²hodnΘ vlastnosti -- nap°. vÜechny metody definovanΘ pro t°φdu Object majφ ·pln∞ vÜechny objekty vyskytujφcφ se v Java systΘmu. Dßle, do prom∞nnΘ deklarovanΘ jako prom∞nnß tΘto t°φdy m∙₧eme ulo₧it odkaz na libovoln² objekt -- vypl²vß to z mo₧nosti uklßdat do prom∞nn²ch odkazy na instance zadanΘho typu nebo libovolnΘho potomka. P°φklad sprßvnΘho ulo₧enφ odkazu na objekt:
Object z = new Zakaznik();
Tento p°φkaz je v po°ßdku, proto₧e t°φda Zakaznik je potomkem t°φdy objekt (jako ostatn∞ i vÜechny ostatnφ t°φdy).
Program v jazyce Java Program v jazyce Java se sklßdß z ·vodnφ sekce a z n∞kolika definic t°φd. Jako prvnφ p°φkaz m∙₧eme pou₧φt p°φkaz package, kter² urΦuje, souΦßstφ kterΘho balφku je naÜe t°φda:
package mujBalik;
P°ipome≥me si, ₧e balφk v podstat∞ znamenß adresß°, ve kterΘm bude umφst∞n p°elo₧en² class soubor. Za p°φkazem package m∙₧e nßsledovat n∞kolik p°φkaz∙ import. P°φkaz import nßm zkracuje zßpis t°φd. SouΦßstφ ·plnΘho jmΘna ka₧dΘ t°φdy je toti₧ jmΘno balφku, ze kterΘho pochßzφ. Pln² zßpis jmΘna t°φdy (v typu prom∞nnΘ) by mohl b²t pon∞kud dlouh². Nap°. pokud pracujeme na projektu ulo₧enΘm v balφku velkyProjekt a jeÜt∞ ka₧d² pracovnφk mß balik na svΘ t°φdy (nap°. novak) museli bychom prom∞nnΘ t°φdy zßkaznφk z tohoto balφku deklarovat nßsledujφcφm zp∙sobem:
velkyProjekt.novak.Zakaznik x;
Pokud se chceme opakovßnφ tohoto zßpisu vyhnout, m∙₧eme pou₧φt p°φkaz import bu∩ na t°φdu zßkaznφk, nebo na cel² balφk novak:
import velkyProjekt.novak.Zakaznik;
Pokud je na zaΦßtku naÜeho souboru jeden z t∞chto p°φkaz∙, m∙₧eme deklarovat prom∞nnΘ typu Zakaznik stejn∞, jakoby byly ulo₧eny v naÜem aktußlnφm balφku. Cel² zdrojov² text v jazyce Java bude tedy obsahovat nßsledujφcφ Φßsti:
package jmeno;
Ka₧d² program by m∞l obsahovat jednu t°φdu, kterß je hlavnφ -- v p°φpad∞ samostatnΘ aplikace je to t°φda obsahujφcφ main, v p°φpad∞ appletu je to potomek t°φdy Applet. Tato hlavnφ t°φda b²vß oznaΦena klφΦov²m slovem public, kterΘ urΦuje, ₧e t°φda je p°φstupnß i z jin²ch balφk∙, ne₧ ve kterΘm se prßv∞ nachßzφme. POZOR: t°φda oznaΦenß jako public m∙₧e b²t v souboru jenom jedna a musφ (!!!) se jmenovat stejn∞ jako jmΘno souboru, ve kterΘm je uvedena (jmΘno souboru je tedy jmΘno tΘto t°φdy zakonΦenΘ koncovkou .java). Soubor m∙₧e obsahovat jeÜt∞ deklarace pomocn²ch t°φd -- tyto t°φdy vÜak nemohou b²t oznaΦeny jako public, tj. nemohou b²t pou₧ity z jin²ch balφk∙ (a soubor∙). Pokud chceme vytvo°it t°φdu pou₧itelnou i mimo nßÜ zdrojov² soubor, musφme ji umφstit do samostatnΘho souboru, oznaΦit ji jako public a soubor pojmenovat stejn²m jmΘnem. Pokud to ud∞lßme a t°φda se p°elo₧φ, m∙₧eme ji pou₧φvat v naÜem k≤du.
Prßce s prom∞nn²mi Jak jsme se ji₧ dozv∞d∞li, prom∞nnΘ v jazyce Java mohou b²t bu∩ n∞kterΘho zßkladnφho typu, nebo typu odkazu na objekt. Pokud je prom∞nnß typu reference na objekt, m∙₧e b²t jejφ hodnotou bu∩ odkaz na objekt t°φdy, kterß je deklarovanß, nebo objekt t°φdy, kterß je potomkem deklarovanΘ t°φdy. Existuje jedna specißlnφ hodnota referenΦnφ prom∞nnΘ, kterß °φkß, ₧e tato prom∞nnß neukazuje na ₧ßdn² objekt. Tato specißlnφ hodnota se oznaΦuje slovem null a m∙₧e b²t dosazena jako hodnota prom∞nnΘ:
Zakaznik z = null;
Tφmto p°φkazem jsme pouze deklarovali prom∞nnou typu Zakaznik, ale nep°i°adili jsme ji jako hodnotu ₧ßdn² objekt. Hodnotu tΘto prom∞nnΘ m∙₧eme urΦit pozd∞ji p°φkazem
z = new Zakaznik();
Pokud deklarujeme dv∞ prom∞nnΘ kompatibilnφch typ∙, m∙₧eme jejich hodnoty vzßjemn∞ p°i°adit nap°. p°φkazem:
Zakaznik novak = z;
Po tomto p°φkazu budou ob∞ dv∞ deklarovanΘ prom∞nnΘ ukazovat na stejn² objekt. To znamenß, ₧e zm∞nφme-li hodnotu n∞kterΘ vlastnosti u prom∞nnΘ z, zm∞nφ se samoz°ejm∞ i vlastnost u objektu, na kter² ukazuje prom∞nnß novak -- jednß se toti₧ o tent²₧ objekt (vytvo°en² jednφm volßnφm p°φkazu new Zakaznik()) -- viz obrßzek Objekty v Jav∞. P°i deklarovßnφ prom∞nnΘ se m∙₧e, ale nemusφ uvΘst jejφ inicializaΦnφ hodnota. Pokud tuto hodnotu neuvedeme, bude po deklaraci hodnota ΦφselnΘ prom∞nnΘ 0, typu boolean false a referenΦnφ prom∞nnΘ null. V definici jazyka Java jsou tyto hodnoty uvedeny, ale je otßzkou sluÜnΘho programßtorskΘho stylu vÜechny prom∞nnΘ inicializovat, proto₧e to podstatn²m zp∙sobem ulehΦφ Φtenφ programu.
V²razy a p°φkazy Zatφm jsme se v∞novali pouze tomu, jak n∞jakΘmu objektu stanovit jeho vlastnosti, p°φpadn∞ mu napsat n∞jakou metodu. To ovÜem samoz°ejm∞ nenφ vÜe, co s prom∞nn²mi a metodami m∙₧eme d∞lat. Z prom∞nn²ch, volßnφ metod, zßvorek a operßtor∙ m∙₧eme sestavovat v²razy podobn∞ jako v jazyce C. U ka₧dΘho operßtoru je urΦeno, jak² typ musφ mφt jednotlivΘ operandy. V nßsledujφcφ tabulce je p°ehled operßtor∙, kterΘ m∙₧ete pou₧φt v jazyce Java:
Operßtory jazyka Java
AritmetickΘ operßtory se chovajφ tak, jak bychom Φekali -- sΦφtßnφ seΦte hodnotu sv²ch argument∙ apod. Zajφmav∞jÜφ je to u operßtor∙ p°i°azenφ. NapφÜeme-li x = y, provede se p°i°azenφ hodnoty, kterß je v prom∞nnΘ y do prom∞nnΘ x a hodnota tohoto v²razu bude p°i°azovanß hodnota. To, ₧e p°i°azenφ je obyΦejn² v²raz, umo₧≥uje pou₧φt nßsledujφcφ syntaxi x = (y = z). Tedy nejprve se hodnota z prom∞nnΘ z p°i°adφ do y a potom do x. Hodnota p°i°azovacφho v²razu mß typ shodn² s p°i°azovan²m typem. Pro porovnßvßnφ pou₧ijeme operßtor ==, kter² porovnß svΘ argumenty a jeho₧ v²sledkem je hodnota typu boolean. Porovnßvßnφ pomocφ == nebo pomocφ != (nerovnß se) budeme Φasto pou₧φvat p°i podmφn∞n²ch p°φkazech a cyklech. Pokud za v²razem ud∞lßme st°ednφk, stßvß se z n∞j p°φkaz. P°φkaz m∙₧e b²t souΦßstφ bloku p°φkaz∙ -- blok p°φkaz∙ je uzav°en ve slo₧en²ch zßvorkßch { }. Ka₧dΘ t∞lo metody tvo°φ jeden takov²to blok. Samoz°ejm∞, ₧e v²razy se mohou sklßdat nejen z operacφ provßd∞n²ch s prom∞nn²mi (vlastnostmi), ale takΘ s v²sledky volßnφ metod:
int vrat10() { return 10; } V tomto p°φkladu se pou₧ije volßnφ metod vrat10 a vrat15 ve funkci fce. Pou₧itφ volßnφ funkcφ (metod) je tedy v jazyce Java stejnΘ jako ve znßm²ch procedurßlnφch jazycφch (C, Pascal). VÜechny aritmetickΘ a logickΘ operßtory se dajφ zkombinovat s p°i°azenφm nßsledujφcφm zp∙sobem:
a += 10; // p°iΦte 10 do prom∞nnΘ a Slo₧enΘ p°i°azenφ tedy nejprve provede uvedenou operaci a v²sledek ulo₧φ zp∞t do prvnφ prom∞nnΘ. Je to vlastn∞ jenom zkratka slou₧φcφ k tomu, aby byl zßpis Φasto provßd∞n²ch operacφ kratÜφ. Tato syntaxe pln∞ vychßzφ z jazyka C.
| <<< | COMPUTERWORLD | IDG CZ homepage | |