300 likes | 586 Views
Kordamine L9. Lihtsustatud ülevaade keele Java üldisest ülesehitusest. Mida ja kuidas tohib kirjutada? Mis selle mõte on?. Java programm on üks või rohkem klassi. Üks neist on peaklass - see, mis sisaldab peameetodit
E N D
Kordamine L9 Lihtsustatud ülevaade keele Java üldisest ülesehitusest • Mida ja kuidas tohib kirjutada? • Mis selle mõte on?
Java programm on üks või rohkem klassi. Üks neist on peaklass - see, mis sisaldab peameetodit Klass kirjutatakse üles klassikirjeldusena: class KlassiNimi{ ... <klassi liikmed: väljad ... konstruktorid ... meetodid> }
Juht I: kui oma programmis kirjeldatavatest klassidest me isendeid ei loo. Sellisel juhul konstruktorid puuduvad ja väljad ning meetodid on piiritlejaga static Piiritlejaga static varustatud välja nimetatakse ka klassiväljaks. Piiritlejaga static varustatud meetodit nimetatakse ka klassimeetodiks.
Meetod on mingi iseseisva ülesande lahendamise kirjeldus. tagastustüüp meetodiNimi(formaalsed parameetrid){ . . . <lokaalmuutujad tegevuseeskiri> . . . } Iga formaalne parameeter kirjutatakse kujul tüüp formaalseParameetriNimi Formaalsed parameetrid eraldatakse komadega.
Küsimus • Mille poolest erineb formaalne parameeter • lokaalmuutujast? • Vastus • On ainult kaks erinevust. • Formaalne parameeter kirjeldatakse sulgudes • meetodi nime järel. Lokaalmuutuja kirjeldatakse • meetodi kehas. • 2. Formaalne parameeter saab algväärtuseks vastava • argumendi väärtuse meetodi väljakutsest, samas kui • lokaalmuutujale omistatakse algväärtus meetodi • täitmise käigus.
Meetodit võib vaadelda funktsiooni analoogina: static double f(double x, double y){ double a; // lokaalmuutuja double b; // lokaalmuutuja double c; // lokaalmuutuja a = 2*x; // omistamine b = 3*y; // omistamine c = (a - b)/17; // omistamine return c; // väärtuse tagastamine }//f f(x, y) = (2x -3y)/17, x ja y ei pruugi olla täisarvud Meetodi lühem variant: static double f(double x, double y){ return (2*x - 3*y)/17; }//f
Sama meetodi variant, kus muutujakirjelduses omistatakse muutujale ka (alg)väärtus: static double f(double x, double y){ double a = 2*x; // lokaalmuutuja double b = 3*y; // lokaalmuutuja double c = (a - b)/17; // lokaalmuutuja return c; // väärtuse tagastamine }//f
NB! Meetod saab Java programmis esineda ainult klassis. Seal on ta klassi liikmeks, seega meetod ei saa olla ka mõne teise meetodi sees. Klassis võib olla kuitahes palju meetodeid. Ühte klassi koondatakse tavaliselt mingis mõttes lähedased meetodid. Nt süsteemklass Math sisaldab matemaatiliste funktsioonide arvutamise meetodeid.
Klass (nimega A), milles on üks meetod (nimega f): class A{ static double f(double x, double y){ // Antud: x ja y // Tulemus: tagastatakse väärtus f(x, y), vt lk 5 double a = 2*x; // lokaalmuutuja double b = 3*y; // lokaalmuutuja double c = (a - b)/17; // lokaalmuutuja return c; // väärtuse tagastamine }//f }//A
Meetodi rakendus (ehk väljakutse) on avaldis KlassiNimi.meetodiNimi(argumendid) mida võib vaadelda funktsiooni arvutamise analoogina: avaldise A.f(7.25, 2.0) väärtuseks on 0.5, sest klassi A meetodit f rakendatakse juhul, kus x == 7.25 ja y == 2.0. Seega meetodi f kohaselt tehakse arvutused a = 2*7.25 (a saab väärtuseks 14.5) b = 3*2.0 (b saab väärtuseks 6.0) c = (a - b)/17 (c saab väärtuseks 8.5/17 = 0.5) Muutuja c väärtus tagastatakse(return c;).
Argumendiks meetodi rakenduses on avaldis. Aritmeetiliste (ehk arvuliste) avaldiste näiteid: 7.25 2.0 2 x 2*x + y A.f(7.25, 2.0) A.f(A.f(7.25, 2.0), x) Math.sqrt(2.0) (süsteemklassi Math meetod sqrt) Math.sqrt(2*x + y)
Meetod, mis ei tagasta väärtust • Tagastustüübiks kirjutatakse • void • (tühitüüp). • Kasutatakse juhul, kui meetodi tegevuste hulka • ei kuulu (leitud) väärtuse tagastamine, st direktiiv • return avaldis; • meetodis puudub. (Võib küll esineda avaldiseta • naasmisdirektiiv return ; .) • Näideteks on • meetod, mis ei peagi mingit väärtust leidma; • meetod, mis leitud tulemuse(d) rakendajale mingil • muul moel teatavaks teeb.
class B{ static void väljastadaJoon(){ // Antud: mitte midagi // Tulemus: konsoolile väljastatakse // miinusmärkidest koosnev joon System.out.println(“-----------------------------”); }//väljastadaJoon }//B Sellise meetodi rakendamise avaldisel väärtus puudub. Avaldise järgi kirjutatakse kohe semikoolon, moodusta- des seega avaldisdirektiivi, nt B.väljastadaJoon(); Viimase “arvutamisel” väljastatakse konsoolile rida miinuseid.
Peameetodil on kindla kujuga päis: public static void main(String[ ] args){ ... }//main Peameetodi nimi on main ja tagastustüüp on void (st ei tagasta väärtust). Peameetodist algab kogu Java programmi täitmine, seda rakendab käituskeskkond. Viimane asjaolu tingib piiritleja public vajaduse.
Peaklass nimega C, milles peameetod rakendab klassides A ja B leiduvaid meetodeid: class C{ public static void main(String[ ] args){ double x = 7.25; double y = 2.0; B.väljastadaJoon(); System.out.println(“x = ” + x); System.out.println(“y = ” + y); B.väljastadaJoon(); System.out.println(“f(x, y) = ” + A.f(x, y)); System.out.println(“f(f(x, y),x) = ” + A.f(A.f(x, y),x)); B.väljastadaJoon(); }//main }//C
Kokkuvõttes on meil nüüd Java programm, mis koosneb kolmest klassist - klass A, klass B, klass C (peaklass). Skemaatiliselt: A f( ) B väljastadaJoon( ) C main( ) Klassikirjelduste tekstid salvestatakse failidesse A.java, B.java, C.java ja kompileeritakse: javac A.java (teeb faili A.class) javac B.java (teeb faili B.class) javac C.java (teeb faili C.class)
Lahendamiseks käivitatakse peaklass: java C (alustatakse peameetodist failis C.class) ----------------------------- x = 7.25 y = 2.0 ----------------------------- f(x, y) = 0.5 f(f(x, y),x) = -1.2205882352941178 ----------------------------- lahendamise tulemus
Meetod (loogiline meetod), mis tagastab väärtusena tõeväärtuse true (tõene, “jah”) või false (väär, “ei”) • Lahendab kontrollimisülesannet - ülesannet, mille • vastuseks on kas “jah” või “ei”. • Tagastustüübiks on boolean • Töö lõpeb tagastusdirektiivi • return loogilineAvaldis; • täitmisega • Meetodi rakendus on loogiline avaldis (selle üks • erijuhte)
Ülesanne: antud on kaks arvu x ja y; kontrollida, kas |x - y| < 0.001. static boolean onLähedased(double x, double y){ double a = Math.abs(x - y); if(a < 0.001) return true; else return false; }// onLähedased Lühem variant: static boolean onLähedased(double x, double y){ return Math.abs(x - y) < 0.001; }// onLähedased Meetodi onLähedased() võiks kirjutada nt klassi A.
Loogiline avaldis ehk tingimus on avaldis, mille väärtuseks on kas true (“jah”) või false (“ei”), st tõeväärtus. Näiteid: true false x >= y a < 0.001 a == b A.onLähedased(x, y) A.onLähedased(3*a, y+0.5*b) (0.0 < x) && (x <= 1.0) (&& - loe “ja”) A.onLähedased(a, y) || (x >= y) (|| - loe “või”) d (kui muutuja d on tüüpi boolean, st kirjeldatud kujul boolean d; )
Küsimus Millal võib (klassi)meetodi rakenduses meetodi päritoluklassi nime ära jätta? St näiteks B.väljastadaJoon(); asemel kirjutada väljastadaJoon(); Vastus Ainult siis, kui meetodit rakendatakse samas klassis, kus meetod on liikmeks. Nt kõikjal klassis B võib miinustest koosneva joone väljastamise korralduse esitada kujul väljastadaJoon();
Näiteks lisame klassi B veel teisegi meetodi; olgu selle nimeks väljastadaTopeltjoon: static void väljastadaTopeltjoon(){ // Antud: mitte midagi // Tulemus: konsoolile väljastatakse // kaks miinusmärkidest koosnevat joont väljastadaJoon(); väljastadaJoon(); }//väljastadaTopeltjoon
Klassiväli on analoogiline meetodiga kasutatavuse mõttes: klassiväli on selline muutuja ehk koht väärtuse hoidmiseks, mida võivad kasutada üldiselt kõik (meetodid). Sellest klassist väljaspool kasutamisel tuleb välja nime ette panna veel välja päritoluklassi nimi. class D{ static double k; // väli static double mm( ){ k = -13.7; ... }//mm }//D class E{ static double nn( ){ D.k = 27.5; ... }//nn }//D
Küsimus Mida tähendab piiritleja private meetodi või välja ees? Vastus Piiritlejaga private varustatud meetodit ega välja pole väljapoole klassi “näha”. Selliseid nn privaatseid meetodeid/välju saab rakendada/ka- sutada ainult selles klassis (selle klassi meetodites). class D{ private static double k; static double mm( ){ k = -13.7; ... }//mm }//D class E{ static double nn( ){ D.k = 27.5; ... }//nn }//D
Juht II: mõnest oma programmis kirjeldatavast klassist kavatseme luua isendeid. Sellisel juhul on klassis vaja konstruktoreid ning (mõned) väljad ja meetodid on ilma piiritlejata static Piiritlejata static välja nimetatakse ka isendiväljaks. Piiritlejata static meetodit nimetatakse ka isendimeetodiks. Loe: Aabits, vihik 2 ja vihik3; leksikon, artiklid isendiloome ja konstruktor.
Java programmi täitmise ajal on iga programmi kuuluva klassi kõik klassiväljad ja klassimeetodid olemas, ja parajasti ühes eksemplaris; sõltumata sellest, kas klassist on isendeid loodud või mitte. Neid (nt klassi K klassivälju ja klassimeetodeid) saab kasutada/rakendada: samas klassis (nt klassis K) lihtsalt nime järgi, teistest klassidest nimega, mille ette on kirjutatud klassinimi ja punkt, nt K.väljaNimi K.meetodiNimi( )
Java programmi täitmise ajal on programmi kuuluva mingi klassi (nt klassi K) isendiväljad ja klassimeetodid olemas ainult selle klassi isenditel. Seega niimitmes eksemplaris kuimitu isendit sellest klassist on parajasti juba loodud. Neid (nt klassi K isendivälju ja isendimeetodeid) saab kasutada/rakendada ainult kindlale isendile osutades ehk: seoses kindla isendiga. Klassi K isendi osutip kirjeldus (suvalises klassis): K p; // p väärtus võib olla viit klassi K isendile või null ... p = new K(...); // p väärtus on viit klassi K vastloodud isendile
(suvalises klassis:) p Klassi K isend Isendiväli x Isendimeetod m( ) this == p p = new K(...); K q = new K(...); ... ... p.x ... q.x ... ... p.m(...) ... q.x(...) q Klassi K isend Isendiväli x Isendimeetod m( ) this == q this on võtmesõna ehk reserveeritud sõna
Küsimus Millal võib isendimeetodi rakenduses isendi osuti meetodi nime eest ära jätta? St näiteks p.m(...) asemel kirjutada m(...) Vastus Ainult siis, kui meetodit rakendatakse samas klassis, kus meetod on liikmeks. Täpsem vastus Ainult siis, kui p väärtuseks on väärtus this, st selle isendi asukoha viit. Veel täpsem vastus Kui isendimeetodi ees ei ole osutit, siis loetakse selleks this. Öeldu kehtib ka isendivälja kasutamise kohta.
Küsimus Millal läheb üldse vaja osutit this ? Vastus 1. Kui konstruktori või isendimeetodi formaalsel parameetril on sama nimi, mis mõnel isendiväljal; kuna formaalne parameeter “varjab” samanimelise välja, siis tuleb välja nime ette kirjutada this ja punkt. 2. Kui mingi meetodi rakenduses tuleb argumendiks anda selle isendi viit (seega this argumendi kohal) [, millega seoses parajasti töötab rakendav meetod.]