Göm menyn

5: Öva på metoder

Syftet med laborationen

När program växer delar man upp den i delar, i delprogram. Dessa delar ger både ökad läsbarhet och möjlighet att återanvända samma delprogram på flera sätt.

I denna laboration ska du bekanta dig med metoder, en subprogram-konstruktion som används i Java. Vi ska begränsa oss till s k klassmetoder (statiska metoder) i laborationen, vilka alltid definieras med modifieraren static. Det du lär dig här gäller dock för alla metoder i Java.

För main-metoden använder vi modifierarna public static. För alla andra metoder kan du normalt använda private static. (Publik synlighet är bara meningsfullt om metoden ska användas utanför klassen där den deklareras, t ex som i fallet main.)

Laborationen har som syfte att du ska förstå hur metoder fungerar. Att lösa problem med hjälp av metoder övas på i senare laboration.

Efter laborationen förväntas du kunna:

  • dela upp ett program i delprogram
  • använda och anropa delprogram i form av statiska metoder i Java
  • använda statiska metoder som funktioner
  • använda statiska metoder som procedurer utan returvärde

Relaterade avsnitt i kursboken: kapitel 8

Ytterligare material och exempel, för den som vill:

Arbeta med vanliga källkodsfiler

Ett java program består av en eller flera källkodsfiler. En av filerna måste alltid innehålla en statisk metod som heter main som är den metod som anropas först när programmet startas.

I denna laboration ska du öva dig på att arbeta med statiska metoder. main-metoden är din "toppmetod" som sedan anropar andra statiska metoder du själv ska definiera.

Tips: I Eclipse när man skapar en ny klass kan man automatiskt generera ett kodskelett genom att välja i checkboxar i skapa-klass-wizard-fönstret. Välj den checkboxen som säger att klassen ska ha en main-metod så skapas en sådan automatiskt.

Uppgift 1: Arbeta i kursbok - Definiera och anropa metoder

Börja med att skapa ett nytt projekt för laborationens uppgifter, t ex MethodProject.

Läs avsnitt 8.1-8.5. Gör följande:

Repetition: 8.1-8.4

Övningar: 8.1-8.3

Uppgift 2: Eget program - metoder för konsolkonst

Skapa en ny klass StarTriangle. Du kan kryssa i att main-metoden ska skapas automatiskt om du vill. Här ska vi göra ytterligare en konsolkonstövning med stjärnor. Denna gång för att prova på att göra metoddefintioner och se hur metoder kan användas för att öka läsbarheten i källkoden.

Metoder har möjlighet att ta indata, s k parametrar. Ett exempel på en metod som har en parameter är main-metoden. Parametern som anges i metoddefinitionen kallas formell parameter. I fallet main heter parametern args (om Eclipse skapat metoden i alla fall) och är där alltid av typen String[]. När du inför egna metoder kan du införa valfria namn på såväl metod, parameter och parametertyp.

Syntaxen för att ange en formell parameter är typ variabelnamn. En metod kan ta flera parametrar, de separeras då med kommatecken.

Lägg till följande rader i main-metoden:

  System.out.println("My Star Triangle");
  printChar('+', 16);
  System.out.println();
  for (int i = 0; i < 16; i++) {
    printStars(i, 16 - i);
    System.out.println();
  }

En metod som tar parametrar måste anropas med argument, också kallade aktuella parametrar, av rätt typ och antal. Ovan är '+' och 16 exempel på aktuella parameterar vid anropet till printChar. Argumenten skrivs innanför parentesen efter metodnamnet vid anrop till en metod. Det är viktigt att ett argument har samma typ som den formella parametern, annars får du kompileringsfel. Vid anropet tilldelas de formella parametrarna argumentens värden, likt en vanlig variabeltilldelning. Tilldelningen nollställs vid varje anrop. Ovan anropas två metoder: printChar och printStars. Vi ser att argumenten anges som uttryck, blandat med både variabler och literala värden.

Uppgift: Definiera metoden printChar så att den skriver ut sitt första argument antalet gånger som ges av det andra argumentet. Definiera därefter metoden printStars som skriver ut stjärnor, där första argumentet anges vänstermarginal och andra argumentet högermarginal för utskriften. Metoden printStars ska anropa metoden printChar. Om definitionerna är rätt gjorda ska konsolutskriften bli:

  My Star Triangle
  ++++++++++++++++
  ****************
   **************
    ************
     **********
      ********
       ******
        ****
         **

Uppgift 3: Eget program - funktion för temperaturomvandling

I denna ska du göra temperaturomvandlingar av en array av temperaturvärden. En metod som returnerar värden implementerar en funktion. Detta är sättet vi använder metoder när vi vill räkna ut ett värde, sett som en funktion av metodens parametrar. Funktionanropets returnerade värde kan vi sedan använda som (en del av) ett uttryck i t ex en tilldelningssats.

I uppgiften ska du omvandla Farenheit till Celsius för alla värden i en array. Översättningen sker med formeln:

  C = 5/9 * (F-32)

Uppgift: Skriv ett program, med klassnamn TemperatureConvertion, som omvandlar en given array med farenheit-observationer till Celcius. Omvandlingen ska ske med hjälp av två metoder som returnerar värden. En metod farenheitToCelcius som omvandlar Farenheit till Celsius för ett enskilt värde. Sen en andra metod arrayOfFarenheitToCelcius som omvandlar en array med Farenheitvärden till Celcius. Därefter ska du göra en metod averageTemperature som returnerar medelvärdet av alla temperaturvärden i en array. Testa programmet på arrayer av olika längd och med olika värden och se att det fungerar.

Uppgift 4: Öva anrop med referenstyp

Arrayer utgör referensobjekt i Java. Detta innebär att en variabel av en array-typ pekar på en array, den håller den inte som ett literalt värde. Detta har vi hittills inte behövt tänka på så mycket. Men det gör, bland annat, att arrayer skiljer sig från primitiva datavärden när de skickas som parametrar till en metod.

Steg 1: Skapa en ny klass som heter ParameterTest. Prova att göra två små testmetoder testInt som tar ett heltal som parameter och testArray som tar en array som parameter. Tilldela heltalsparametern ett nytt värde i metoden testInt. Ändra innehållet i array-parametern till testArray på lämpligt sett. Sen prova att göra följande main-metod:

  int x = 5;
  testInt(x); // anropa testInt med ett heltal
  System.out.println(x);
  int[] a = {0,4,5,7};
  testArray(a); // anropa testArray med en array
  for (int y : a) {
    System.out.print(y + " ");
  }

Vad har hänt med värdet på x och a efter anrop av testInt och testArray? Fundera över varför de reagear olika. Observera att Java alltid anropar med en kopia av argumentvärdet (eng. call by copy), men vad är argumentvärdet för en array? Jo, en referens. Men det som den refererar till, själva arrayen, kommer vara densamma i anropande och i anropad metod. Prova ytterligare en variant för array-versionen av test: tilldela parametern en helt ny array. Prova och kör igen. Förstår du varför den ändringen inte påverkade anropande metod alls?

Att arrayer beter sig så här är i många fall en fördel. Det innebär att vi kan förändra en eller flera arrayer i en metod, utan att behöva returnera dem som "nya" funktionella värden. I följande uppgift ska vi utnyttja det för att ändra värdet på alla värden i en array som en "matematisk vektor".

Steg 2: Skapa ett program VectorOperations och deklarera följande metoder utan returvärde:

  • add: tar ett flyttal och en array av flyttal som parametrar samt utför en addition av givet flyttal på alla array-element
  • mult: tar ett flyttal och en array av flyttal som parametrar samt utför en multiplikation av givet flyttal på alla array-element
  • invert: tar en array av flyttal och utför en invertering (1 delat med x) av alla array-element.

Som test av dina metoder utför följande "operationer" på en array i main-metoden:

  double[] vector = {0.14, 23.5, 33.4, 17.4, 89.76};
  add(7.3, vector);
  invert(vector);
  mult(34.0, vector);

Efter att dessa rader exekverats ska värdena i vector vara:

  4.56989247311828 1.1038961038961037 0.8353808353808354 1.376518218623482 0.3502987842571605 

Prova med flera vektorvärden och se att det fungerar som det ska, t ex med en tom array.

Uppgift 5: Eget program - en egen signummetod

En funktionell metod använder ju kommandot return för att returnera dess värde. När vi använder villkor i metodens källkod så är det ofta lämpligt att använda flera retur-satser för olika slags värden. När vi använder villkor är det också ofta en bra idé att lägga själva villkoret i en egen funktionell metod som returnerar ett booleskt värde. I denna uppgift ska du träna på bägge dessa saker.

Uppgift: Skapa en klass MyMath. I denna klass ska du skapa din egen version av Math-klassens metod signum, dvs en funktionell metod som returnerar -1 för negativa tal, 0 för 0, och 1 för positiva tal (se föregående labb). Din nya metod signum ska i sin tur använda tre funktionella metoder som tar ett heltal som argument och returnerar ett Booleskt värde:

  • isPositive: returnera true om talet är positivt, false annars
  • isZero: returnera true om talet är noll, false annars
  • isNegative: returnera true om talet är negativt, false annars

Prova att dina nya funktionella metoder fungerar som de ska genom att testa med följande källkod i din main-metod:

  int number = 7;
  System.out.println(signum(number));
  number = -5;
  System.out.println(signum(number));
  number = 0;
  System.out.println(signum(number));

Om signum fungerar rätt ska följande skrivas ut:

  1
  -1
  0

Redovisning

Redovisa laborationen muntligt för labbhandledare.


Sidansvarig: Johan Jernlås
Senast uppdaterad: 2011-01-21