Föreläsigar 7,8 sept 4, sept 6 v 39). delvis DD Chapter 6. Metoder som returerar värde. När vi skriver uttryck ka vi aväda ibyggda operatorer, t ex i uttrycket efter tilldeligssymbole i satse : k = 3*i + j + 4; I uttryck också aväds arop (egelska call, ivocatio) till metoder som fis i färdigskriva klasser på likade sätt som i matematike aväder stadardfuktioer. Så här skrivs till exempel att variabel x (lite del av miet) skall iehålla värdet för sius för 0.5 radiaer och att y skall iehålla cosius för π /4 + absolutvärdet av iehållet av x: x = Math.si(0.5); y = Math.cos(Math.PI/4.0) + Math.abs(x); //Obs paratesera! I e matte -bok skulle det stå x = si 0.5 och y = cos π/4 + x Me hur gör ma om ma vill defiiera ega fuktioer (metoder som returerar värde), och hur aväder ma dem, kaske gåg på gåg? Jo: Java Matte Defiitio av f: f(x) x R R.. class...{ static double f(double x) { Vi defiierar f(x) = x +3 retur x+3; Vi kallar x för (formell) parameter, i matte ofta variabel som ju betyder ågot helt aat i programmerig! Avädig (arop, applikatio) av f...mai(...) { utdata.pritl("f(14.0) = " + f(14.0)); Vad blir f(14)? z = 1; Om z = 1, u = 3.0* f(.0*z); låt u = 3*f(*z) Vi kallar 14.0 och.0 för argumet (i vissa böcker aktuell parameter).
Ytterligare ett exempel. s formel : I e matte-bok ka det stå så här: Om e triagel har sidor med lägdera a, b och c ka triagels yta beräkas med s formel: area(a,b,c) = p(p-a)(p-b)(p-c) där p = (a+b+c) / Beräka ågra triaglars ytor, t ex de egyptiska triagel med sida 3, 4 och 5. Övig: I formel är e sorts operator utlämad. Vilke? Får ma göra så i Java? Detta blir i Java: import java.io.*; public class { static BufferedReader idata = ew BufferedReader(ew IputStreamReader(System.i)); public static void mai(strig[] iargs) throws IOExceptio { System.out.pritl("s formel beräkig av triaglars ytor"); System.out.prit("Ge lägde för sida a : "); double a = Double.parseDouble(idata.readLie()); System.out.prit("Ge lägde för sida b : "); double b = Double.parseDouble(idata.readLie()); System.out.prit("Ge lägde för sida c : "); double c = Double.parseDouble(idata.readLie()); System.out.pritl("Triagels yta = " + area(a, b, c)); public static double area(double ia, double ib, double ic) { double p = (ia + ib +ic) /.0; //s formula retur Math.sqrt(p*(p-ia)*(p-ib)*(p-ic)); /* Körresultat s formel för beräkig av triaglars ytor Ge lägde för sida a : 3.0 Ge lägde för sida b : 4.0 Ge lägde för sida c : 5.0 Triagels yta = 6.0 */ Exemplet visar också hr ma matar i e sträg frå tagetbordet och hur resultatet bifogas som e flerraders-kommetar. Detta är bekvämare ä att aväda JOptioPae för imatig. Defiitoe av utdata förklaras seare.
Sematik = Programmets betydelse. 1. Före mai börjar köra : ALU + CPU (styrig, aritmetik, mie) Dators mie Klassvariabler System out Metodarop, parameter lokala variabler iargs mai(..) a b c Objekt..readLie.. Klassmetoder..mai....area.. idata..pritl.. Double parsedouble Dators skärm Tagetbord När vi startar iterpreter med java startar mai-metode. Dators mie iehåller då dessa metoder och variabler : - Klassvariable System.out refererar till ett objekt som håller reda på skärme och har metode pritl(strig..) som gör att vi ka skriva på skärme. Mer om objekt seare. - Klassvariable idata refererar till ett objekt som håller reda på tagetbordet och har metode Strig readlie() som gör att vi ka läsa i strägar. - Kod för klass-metodera void mai(..) och double area(..) som hör till klasse. - Kod för klassmetode double parsedouble(strig..) som hör till klasse Double. - Dessutom kommer det så läge metode mai exekverar (dvs hela tide) fias e aktiverigspost (frame) för mais parameter iargs samt mais lokala variabler a, b och c.
. När mai kört imatigskommadoa me ite gjort aropet till area : De sju första kommadoa i mai fyller mais lokala variabler a, b och c med värde : ALU + CPU (styrig, aritmetik, mie) Dators mie Klassvariabler System out Metodarop, parameter lokala variabler iargs a b c 3.0 4.0 5.0 mai(..) Objekt..readLie.. Klassmetoder..mai....area.. idata..pritl.. Double parsedouble Dators skärm Tagetbord
3. När mai gjort aropet till area : Miet iehåller u ytterligare e aktiverigspost: - Så läge metode area kör (exekverar) fias e aktiverigspost (frame) för areas parametrar ia, ib, och ic samt areas lokala variabel p. Parmetrara får iitialvärde som är lika med de värde som argumete i aropet har: System.out.pritl("Triagels yta = " + area(a, b, c)); // i mai public static double area(double ia, double ib, double ic) { Första argumetet är uttrycket a som har värdet 3.0 (iehållet i a just u) och detta värde blir iitialvärdet för parameter ia. Pss fylls parameter ib med värdet i variabel b och ic värdet i c. Parametrara fugerar i fortsättige som lokala variabler. ALU + CPU (styrig, aritmetik, mie) Dators mie Klassvariabler System out idata Metodarop, parameter lokala variabler iargs a b c ia ib ic p 3.0 4.0 5.0? 3.0 4.0 5.0 mai(..) area(..) Objekt..readLie....pritl.. Klassmetoder..mai....area.. Double parsedouble Dators skärm Tagetbord
4. När area gjort tilldelige till p : Metode area kör u igåg coh beräkar lokala variable p till ( 3.0 + 4.0 + 5.0 )/.0 = 6.0. Metode areas aktiverigspost ser u ut så här : ia ib ic p 3.0 4.0 5.0 6.0 area(..) 5. När area kört klart och mai kör sitt sista kommado : Det sista metode area gör är att beräka sitt retur värde och lämar detta resultat i CPU:. Metode areas aktiverigspost försvier. Metode mai fortsätter u med att köra sitt System.out.pritl-kommado, som avbröts av aropet. Vid beräkig av pritl-kommados argumet, "Triagels yta = " + area(a,b,c), ka resultatet av aropet till area, som fis i CPU- avädas: ALU + CPU (styrig, aritmetik, mie) Dators mie Klassvariabler System out idata 6.0 Metodarop, parameter lokala variabler iargs a b c 3.0 4.0 5.0 mai(..) Objekt..readLie....pritl.. Klassmetoder..mai....area.. Double parsedouble Dators skärm Triagels yta = 6.0 Tagetbord
Metoder som returerar itet (void). När vi skriver uttryck, i t ex tilldeligar och aropsuttryck, har vi alltså glädje av metoder som returerar värde, speciellt om vi på flera ställe i ett program behöver samma metod. Om vi på flera ställe i ett program har ågra kommado som i stort sett gör samma sak skulle det vara bra att ha ett egetillverkat "super"-kommado som vi kude aväda på dessa ställe. Exempelvis om vi i ett spel-program på flera platser har skrivit dessa satser: System.out.prit("Ställig : "); for (it i = 0; i <= talnu; i = i+1) { System.out.prit(" " + i); System.out.pritl(); Vi ka u i stället skriva (på alla platser där ställige ska skrivas ut): tryckställig(talnu); om vi defiierar e y metod void tryckställig(it ital) på detta sätt: public static void skrivställig(it ital){ System.out.prit("Ställig : "); for (it i = 0; i <= ital; i = i+1) { System.out.prit(" " + i); System.out.pritl(); Äve void-metoder ka defiieras med parametrar och aropas med argumet p s s sätt som returerade metoder. Det fugerar på samma sätt med e y aktiverigspost. Aktiverigsposte för void skrivställig(it ii) har alltså e e parameter för parameter ital. I blocket för for-satse tillkommer e "låda" för blockets lokala variabel i. Avädig av metoder. Att defiiera och aväda metoder krävs praktiskt taget så fort ett program blir ågotsåär stort. Om ma skriver sia ya metoder geerella ka ma t o m ha glädje av dem i adra sammahag. De förtjäar då att ligga i ega klasser och förklaras till public. Ma ka t o m ha glädje av adras klass-metoder frå färdigskriva och färdigkompilerade klasser. Det är detta vi gör med t ex aropet Double.parseDouble. Arope skrivs som <Klassam>.<metodam>(<argumetlista>). Ev krävs import.
Partiella fuktioer och ekel rekursio. Vi defiierar i matte 0! = 1! = (-1)! * för >0 dvs 5! = 4!*5 = (3!*4)*5 = ((!*3)*4)*5 = (((1!*)*3)*4)*5 = ((((0!*1)*)*3)*4)*5 = ((((1*1)*)*3)*4)*5 = (((1*)*3)*4)*5 = ((*3)*4)*5 = (6*4)*5 = 4*5 = 10 me ma ka också räka så här! = 1**... * dvs 5! = 1**3*4*5 =... 10 Ett program som aväder båda sätte att täka : import java.io.*; public class TestFak { static BufferedReader idata = ew BufferedReader(ew IputStreamReader(System.i)); public static void mai( Strig args[] ) throws IOExceptio { //fixa för första varv System.out.prit("Ge ett värde (slute ge <0 ): "); it = Iteger.parseIt(idata.readLie()); while ( >= 0) { //gör det viktiga System.out.pritl("! (Iterativt) = " + fakiter()); System.out.pritl("! (Rec) = " + fakrec()); //fixa för ev ytt varv System.out.prit("Ge ett värde (slute ge <0 ): "); = Iteger.parseIt(idata.readLie());
// retuerar oll för egativa public static it fakiter(it ) { it result = 1; for (it i = 0; i < ; i = i+1) { result = result*(i+1); retur result; // avbryter programmet för egativa public static it fakrec(it ) { if ( < 0) { throw ew RutimeExceptio("Tried to do! for <0"); else if ( == 0 ) { retur 1; else { retur fakrec(-1)*; De lokala variblera i de eda aktiverigsposte i fakiter(it ) vid körig av for-surra: result i 5 0 1 result i 5 1 result i 5 6 result i 5 3 4 result i 5 4 10 De lokal variable (parameter ) i aktiverigspostera och returvärdet i ALU: i fakrec(it ) vid de rekursiva körige: 1 1... 5 5 5 5 5 5 5 5 4 4 4 4 4 4 4 3 3 3 3 3 3 1 1 0 1
Dubbel rekursio. Ett program som gör två rekursiva arop: import java.awt.*; import javax.swig.*; public class DrawTree exteds JApplet { private fial it startmodul = 30; public void pait(graphics g) { drawtree(g, 500, 10, 0, 30*startmodul); private void drawtree(graphics g, it i, it j, it iv, it storlek) { it modul = storlek/30; if (iv == 5) { g.drawoval(i-5*modul, j-5*modul, 8, 8); else { g.drawlie(i, j, i + 8*modul, j + 30); g.drawlie(i, j, i - 8*modul, j + 30); drawtree(g, i + 8*modul, j+30, iv+1, 15*modul); drawtree(g, i - 8*modul, j+30, iv+1, 15*modul); Program av detta slag är svåra att skriva uta rekursio. Körresultat: