Observera att detta är en arbetsversion av sidan!
Dölj style3dev.css för att bli av med annoteringarna!

Lektion 2: Introduktion till metoder

Syfte: Att förstå vad en metod är och varför man använder metoder. Övningar på att använda och skriva metoder.
Begrepp som introduceras: Objekt, objektreferenser, metoder, metodanrop, parametrar, argument, lokala variabler, programkommentarer. main-metoden och utskrifter med println. Kompilering och kompileringsfel.
Arbetsform: Arbeta gärna tillsammans med någon men skriv egen kod. Diskutera med varandra!
Uppskattad arbetstid: 2 - 3 timmar.
Redovisning: Ingen obligatorisk redovisning men diskutera med handledare om det är något du är osäker på!

Hämta två Java-filer

Under den här lektionen skall du öva på att anropa s.k. metoder och sedan själv skriva egna metoder. Du ska att utgå från de två färdiga klasserna ("javaprogrammen") World och Turtle som du skall börja med att ladda ner (om du inte redan gjort det):

  1. Skapa mappen turtleWorld. Visa hur man gör!
    På institutionens Linux-datorer gör du så här:
    1. Öppna filhanteraren genom att välja
      Applications> Accessories> Files
      Ett fönster visas med namnet Home.
    2. Högerklicka i det fönstret och välj att skapa en ny mapp med New Folder och ge namnet turtleWorld.
    Alternativ sätt som kan vara bra att kunna:
    1. Öppna ett terminalfönster genom att välja
      Applications> Accessories> Terminal
    2. Ge unix-kommandot
      mkdir turtleWorld
      i det öppnade terminalfönstret.
  2. Hämta klasserna Turtle.java och World.java och lägg dem i mappen turtleWorld (högerklicka och "spara som").
    På Linux
    Högerklicka på respektive fil och och välj Save Link As
  3. Starta DoktorJava
  4. Öppna de nedladdade filerna med knappen DrJaja-knappen Turtle.java och World.java.
    Det dyker upp en massa text i den så kallade Definitionsrutan. Ignorera den tills vidare!
  5. Tryck på -knappen i menyn.

Se en utförligare beskrivning om något verkar oklart.

Nu är klasserna färdiga att användas.

Att skapa objekt

Skapa ett fönster genom att i interaktionsrutan skriva:
World w = new World(400,400);

Det vi skapade med denna Javasats kallas för ett objekt.

new är en operator som skapar objekt och returnerar en referens till det som skapats. Variabeln w håller reda på ("refererar till") objektet som representerar ett fönster på skärmen.


Skapa en sköldpadda i världen w:
Turtle t1 = new Turtle(w);

Vi har nu två objekt.

Observera att variabeln t1 inte är själva paddan utan en variabel som håller reda på (refererar) paddan.

På samma sätt är w inte världen utan en referens till världen.

Detta kan åskådliggörs så här: Två objekt
Genom att skriva objektreferenserna i interaktionsrutan så får man information om som de refererar.
Prova!
w
t1
Kom ihåg: Javasatser ska normalt avslutas med semikolon. I DrJavas interaktionsruta gäller dock att semikolon får utelämnas och att värdet av uttrycket/satsen i så fall skrivs ut.

Att gör saker med objekt

Man använder så kallade metoder både för att "säga åt" objekt att göra olika saker. Padd-objekten har, bland annat, en metod som flyttar paddan framåt.
Prova!
t1.move(50);

Detta är ett exempel på punktnotation. Till vänster om punkten står en referens till det objekt som ska påverkas (t1). Till höger står namnet på den metod som ska utföras (move i detta fall). Namnet är naturligtvis valt så att det ska berätta vad metoden gör.
Efter namnet kommer ett så kallat argument (även kallat aktuell parameter) inom parantes. Argumentet skickar information till metoden som närmare specificerar uppgiften. I detta fall anger argumentet att den ska förflytta sig 50 bildpunkter ("pixlar").

Prova!
Turtle t2 = new Turtle(w);
t2.move(-70);
t1.turn(45);
t2.turn(-135);
t2.turn(50);
t1.turnTo(0,0);
t2.turnTo(400,400);
t1.turnTo(t2);
t2.turnTo(t1);
Kom ihåg att du kan få textinformation om paddorna genom att bara skriva t1 respektive t2!

Frågor

  1. Metoden turnTo finns uppenbarligen i två versioner. Vilka? Hur vet man vilken version som används när metoden anropas? Svar
    Den ena har två parametrar (av typen int), den andra har en parameter (av typen Turtle). Det är antal och typ av argumenten som avgör vilken metod som avses.
  2. Vilken funktion verkar informationen som står inom parentesen ha när man anropar en metod? Svar
    Informationen som står inom parenteserna vid anrop kallas för argument eller aktuella parametrar och dessa innehåller information som förs över till den anropade metoden.
  3. Varför skriver man t1.move(50) och t2.move(50)? Varför räcker det inte med att skriva move(50)? Vad händer om du skriver move(50)? Svar
    Det som står till vänster om punkten anger vilket objekt som avses. Om man bara skriver move(50) här (i interaktionsrutan) vet inte systemet vilken padda som ska flyttas.

Som du har sett så lämnar paddorna spår efter sig. Detta kan vi utnyttja för att rita figurer, vilket vi skall gör i nästa övning.

Stäng nu det fönster du skapat (klicka i krysset i fönstrets stängningsknapp).

Övning

Rita en kvadrat på följande sätt:

Det går inte att skriva t1.ritaKvadrat() (prova!) Varför fungerar det inte?

Felaktiga uttryck

Flera av nedanstående uttryck är felaktiga. Prova dem och försök förstå felmeddelandena!
Prova!
Turtle t3;
t3.move(50);
Turtle t4 = new Turtle(w2);
Turtle t5 = new Turtle();

Definiera egna metoder

I DrJavas vänstra ruta ser du namnen Turtle.java och World.java. Det är namnen på de två aktuella filerna med Java-kod.

Klicka på Turtle.java!

Det kommer se ut ungefär så här: Turtlekod
Tryck här om radnumren i vänsterkanten saknas.

Gör så här för att få radnummer:
Klicka på -knappen i DrJava,
välj sedan
Preferences > Display Options
och bocka för
Show All Line Numbers.
Avsluta med OK.

(-knappen återfinns på olika ställen på olika system.)

Nu skall du lägga in en egen metod i klassen Turtle.

Scrolla ner till botten i definitionsrutan. Nya metoder skall placeras i det område som här har markerats med rosa, dvs raden efter //, men före tecknet } Bild
Prova detta!

Kopiera och klistra in vidstående rader på den plats som markerats med rosa färg.
public void ritaKvadrat() { this.turn(90); this.move(30); this.turn(90); this.move(30); this.turn(90); this.move(30); this.turn(90); this.move(30); }

Tryck på knappen i DrJava.
Om du inte skrivit fel så kommer texten

Compilation completed.

Obsolete! Detta ska inte hända numera!
(Det kan hända att det markeras ett fel på rad 2 därför att det finns ett konstigt tecken precis framför texten fverstedt. Ändra i så fall det tecknet till ett Ö. Kompilera igen.
Detta är en illustration av hur olämpligt det är att använda nationella tecken som å, ä och ö till och med i kodkommentarer!)

i rutan .

Kompileringen innebär att koden granskas så att den följer Javas regler. Om kompileringen går bra skapas en fil med namnet Turtle.class. Denna fil innehåller de instruktioner som används när programmet körs.

Kontrollera att du har de båda filerna i mappen turtleWorld!

Programmet som utför kontrollen och översättningen kallas av för en kompilator.

Innan vi tittar närmare på metoden skall vi prova den:

  1. Tag bort den gamla världen genom att stänga rutan som världen visas i.
  2. Skapa en ny värld w.
  3. Skapa två paddor t1 och t2.
  4. Flytta den ena paddan 100 steg bakåt.
  5. Säg åt paddan t1 att rita en kvadrat genom att skriva t1.ritaKvadrat().
  6. Säg åt paddan t2 att rita en kvadrat.

(Kom ihåg att, trots att vi skriver "paddan t1" så är t1 inte själva paddan utan bara en referens till paddan.)

Beståndsdelarna i metoden ritaKvadrat

Definitionen av metoden består av två delar:
  1. Metodhuvud. Det är den första raden i metoden public void ritaKvadrat() (Egentligen från och med public till första { - ett metodhuvud kan skrivas på flera rader.)
  2. Metodkropp. Det som finns mellan "måsvingarna" { och }.

Metodhuvudet består av följande:

public Metodens synlighet. Just public betyder att alla kan se och använda denna metod.
void Anger vilken datatyp metoden returnerar. Just void anger att metoden inte returnerar något värde.
ritaKvadrat Metodens namn.
() Mellan parenteserna anger man metodens parametrar. Dessa innehåller information som man vill ge till metoden. I detta fall alltså ingenting.

I metodkroppen står ordet this framför alla metodanrop. Det syftar på att det är just den här paddans metod som avses. När vi skriver t1.ritaKvadrat() så kommer this att referera samma padda som t1 medan this i anropet t2.ritaKvadrat() kommer referera samma padda som t2.

Anmärkning: Det går faktiskt bra att utelämna this i metodkroppen i till ritaKvadrat. Om inget anges så är det "det egna objektet" som avses.

Man kan säga att metodhuvudet anger hur man kan anropa metoden och metodkroppen anger hur metoden löser uppgiften.

Frågor

  1. Vad är en metod? Vad är syftet med metoder? Vad skulle hända om man inte hade några metoder alls? Svar

    En metod är en namngiven samling instruktioner som kan anropas från flera olika ställen. Vid anropet kan extra information skickas med via parametrar som ger detaljer för utförandet.

    Utan metoder skulle koden blir mycket lång, ostrukturerad och full av nästan identiska sekvenser av instruktioner.

  2. Hur ska en metod se ut? Svar
    Se ovan!
  3. Varför kan man nu skriva t1.ritaKvadrat() när att det inte gick förut? Svar
    Vi har nu lagt till metoden ritaKvadrat i klassen Turtle. Förut fanns den inte.
  4. Du har placerat metoden ritaKvadrat i filen Turtle.java. Varför skulle det inte fungera om man öppnade filen World.java och placerade den där? Svar
    Filen World.java innehåller klassen World. Denna klass har inte metoder som move, turn, ...

Lokala variabler

En metod kan ha lokala variabler. De variablerna finns bara i den metod där de är deklarerade.


Vi kan definiera en metod ritaKvadrat30 på detta vis:
public void ritaKvadrat30() { int sida = 30; this.turn(90); this.move(sida); this.turn(90); this.move(sida); this.turn(90); this.move(sida); this.turn(90); this.move(sida); }

Variabeln sida deklareras inuti metoden (dvs i metodkroppen). Det blir då en lokal variabel. En sådan existerar bara i metoden (egentligen i den "klammeromgivning" { ... }) som den är deklarerad i.

En lokal variabels värden sparas inte när man lämnar metoden (omgivningen) och det går inte att använda den utanför metoden.

Gör följande

  1. Kopiera metoden och klistra in den sist i filen Turtle.java.
  2. Spara och kompilera ().
  3. I interaktionsrutan skapa en värld med en padda och anropa metoden ritaKvadrat30() för den paddan för att bekräfta att metoden fungerar, dvs göra samma sak som ritaKvadrat().
  4. Testa att använda den lokala variabeln sida i metoden ritaKvadrat() genom att:
    • ändra this.move(30) till this.move(sida).
    • Spara och kompilera.
    • Läs felmeddelandet och förklara i egna ord varför det inte fungerar.

Vi skulle på samma vis kunna definiera ritaKvadrat40, ritaKvadrat50 etc. Detta skulle dock bli mycket omständligt. I stället använder vi parametrar vilket vi nu tar upp.

Metoder med parametrar

Du har redan använt parametrar i anrop till bl. a. till metoderna move och turn där parametern anger hur långt paddan ska gå respektive hur mycket den ska vrida sig.

Du ska nu lägga till en metod som ritar en kvadrat där sidans längd bestäms av en parameter.

Prova detta!

Kopiera dessa rader till Turtle-klassen. Lägg dem efter den gamla ritaKvadrat (men före den avslutande måsvingen)
public void ritaKvadrat(int sida) { this.turn(90); this.move(sida); this.turn(90); this.move(sida); this.turn(90); this.move(sida); this.turn(90); this.move(sida); }

Kompilera!

Prova detta!
Testa metoden genom att skapa en värld med en padda (t1) och anropa metoden så här: t1.ritaKvadrat(50); t1.ritaKvadrat(100);

Metodens huvud är public void ritaKvadrat(int sida). Här kallas sida för en (formell) parameter och int betyder att denna parameter är av typen int.

För att använda den metoden måste vi skicka med ett värde till parametern vilket vi gör genom att i anropet anger ett värde mellan parenteserna. Värdet som vi anger vid anropet kallas argument eller aktuell parameter.

Vid anropet överförs värdet av argumentet till den formella så att sida alltså får värdet 50.

Man kan säga att en (formell) parameter fungerar som en lokal variabel som får sitt initiala värde från argumentet.

Observera att vi nu har två olika metoder med namnet ritaKvadrat. Det är anropet som avgör vilken metod som används. Har vi ett argument (av heltalstyp) så är det ritaKvadrat(int sida) som används och om vi anropar utan argument så används definitionen utan parametrar.

Prova att anropa ritaKvadrat med ett argument med flyttalsvärde! Vad händer?

Möjligheten att ha flera olika metoder med samma namn kallas generellt för överlagring.

Metoder med flera parametrar

En metod kan ha flera parametrar.
Prova detta!

Kopiera denna metod till din padda och testkör den.
public void ritaFlagga(int stang, int flaggsida) { this.move(stang); this.ritaKvadrat(flaggsida); }

Anmärkning: Java tillåter nationella tecken som å, ä och ö i variabelnamn så stång vore OK men vi avråder ändå bestämt från detta. Dessa tecken ställer ofta till trassel när man flyttar filer mellan olika system och dessutom stödjer inte alla verktygsprogram dem.

Här ser du att metoden ritaFlagga anropar metoden ritaKvadrat som du alldeles nyss skrivit. När man skriver program försöker man i allra möjligaste mån utnyttja metoder som redan existerar och som löser delproblem.
Kopiera in metoden ritaFlagga i klassen Turtle och kompilera.

Prova detta!
Se vad som ritas av dessa rader: t1.ritaFlagga(100,50); t1.ritaFlagga(50,100);

När man anropar metoder med flera parametrar så är det viktigt att man håller reda på ordningen!

Du ser att flaggorna ritas horisontellt. Ett sätt att rätta till detta är att överst i metoden ritaFlagga lägga in satsen: this.setDirection(270) vilket medför att metoden börjar med att rikta paddan rakt uppåt (270 grader medurs) så att flaggan ritas vertikalt. Gör denna förändring, kompilera och testa att det fungerar.

Sammanfattning parametrar

Parametrar används för att föra över information till en metod från den som anropar (använder) metoden.

I metoddeklarationen anges de parametrarna med namn och typ.
Exempel: ritaFlagga(int stang, int flaggSida)

När metoden anropas anges argumenten (de aktuella parametrarna). Som argument kan vilket uttryck som helst av rätt typ användas.
Exempel: ritaFlagg(100, 2*n + 1) (under förutsättning att n är av heltalstyp).

Argumenten och parametrarna måste överensstämma i ordning och antal.

För typerna gäller samma regler som vid tilldelning dvs typen på argumentet måste kunna tilldelas typen på den formella parametern. Man kan alltså skicka ett heltalsvärde till en metod som deklarerat parametern som flyttal men inte tvärt om.

Om argumentet är ett uttryck så beräknas värdet av uttrycket först och det är det värdet som förs över till den parametern.

Ytterligare några metoder i Turtle

I klassen Turtle finns bland andra också metoderna enablePath, disablePath, setVisible och setDirection.

Paddorna kan fler konster:

Prova!
t1.disablePath();
t1.move(25);
t1.enablePath();
t1.move(25);
t1.setVisible(false);
t1.move(25);
t1.setVisible(true);
t1.move(25);
t1.setDirection(90);
t1.move(50);
t1.setDirection(225);
t1.move(50);

Om du vill veta mer om klassen Turtle så kan du läsa den fullständiga dokumentationen (dock ej de metoder du själv lagt in i klassen under denna lektion).

Objektmetoder kontra klassmetoder

De metoder vi introducerat i denna lektion kallas för objektmetoder eftersom de metoderna används på objekt. När man använder en metod på ett objekt säger man att man skickar ett meddelande till objektet, och ber det utföra något, dvs exekvera metoden.

Den andra typen av metoder kallas klassmetoder (även statiska metoder) eftersom de anropas genom att ange klassens namn före metodens namn. Klassen Math som du övade på i lektion 1 är ett exempel på en klass som innehåller klassmetoder. Exempel: double x = Math.sqrt(14.0);.

Metoden main

Hittills har interaktionsrutan använts för att köra (exekvera) koden, exempelvis:
World w = new World(400,400); Turtle t = new Turtle(w); t.drawCircle(50);
Detta fungerar bra när man vill testa enskilda satser men om man vill ha flera satser utförda så är det enklare att samla dessa i en metod och sedan anropa metoden.

Det finns en metod med speciell status som heter main. Den körs (vanligen) genom att man ger ett Run-kommando som i DrJava finns som en knapp i menyraden nära -knappen.

För att det skall fungera skall koden för main-metoden ha följande definition:

public static void main(String[] args) { en eller flera Java-satser }
Dessa satser kommer att utföras när man trycker på -knappen
Observera: Metodhuvudet måste se ut exakt som det visade, dvs
public static void main(String[] args)
Parametern args får heta något annat men i praktiken låter man den alltid heta args eller arg.

Betydelsen av ordet static liksom "hakparenteserna" [] återkommer vi till senare i kursen men de måste vara med!

Prova detta!

Kopiera denna metod till din Turtle-klass.
Lägg gärna till anrop till flera metoder!
public static void main(String[] args) { World w = new World(400,400); Turtle t = new Turtle(w); t.ritaKvadrat(50); t.disablePath(); t.move(50); t.enablePath(); t.ritaKvadrat(100); }

Kompilera med och kör med !

Detta är det normala sättet att arbeta med program. Att skriva kod i interaktionsrutan är, som sagt, bara lämpligt för att testa små uttryck.

Metoden main behöver inte ligga i klassen Turtle som följande övning visar:

Skapa en ny klass genom att trycka på i menyraden. Skriv nedanstående. Klassen kommer då att heta TestTurtles (men det går att ge den vilket legalt namn som helst).
public class TestTurtles { Början av klassdefinitionen.
   public static void main(String[] args) { Början av main-metoden.
Lägg in satser som skapar en värld med några paddor och flyttar dem.
   } Slutet på main
} Slutet på klassdefinitionen
När du kompilerar kommer DrJava be dig spara filen. Den kommer också föreslå namnet TestTurtles vilket du ska använda. (Filen måste ha samma namn som klassen.)

Kör sedan med -knappen vilket bör resultera i ett fönster med paddor.

Notera:

  • Du har nu två main-metoder som båda använder klasserna Turtle och World. Eftersom en main-metod ofta använder många klasser är det normala att metoden ligger i en separat klass och inte i någon klass som metoden använder.
  • När -knappen används körs den main-metod som finns i den klass som är markerad (och vars kod syns i Definitionsrutan). Om det inte finns någon main-metod i den klassen fås ett felmeddelande.

Utskrifter

Hittills har vi kunnat få information om vad en variabel innehåller bara genom att skriva dess namn i interaktionsrutan. Det fungerar inte att i main-metoden bara skriva ett variabelnamn. Det finns inte heller något sätt att från interaktionsrutan komma åt variablerna i main (eller i någon annan metod). Det finns dock särskilda metoder för att åstadkomma utskrifter.

De två enklaste metoderna heter print och println. Den finns dock inte direkt tillgängliga utan måste anropas via referensen System.out.

Exempel:

System.out.println("Hej du glade!"); System.out.println("exp(2) = " + Math.exp(2));

Lite mer information om dett finns i denna minilektion.

Övning

Låt main-metoden i övningarna ovan skriva ut information om paddan och världen!

Kommentarer i programkod

En viktig del av koden är kommentarerna. Dessa påverkar inte programmets funktion utan är förklarande upplysningar till människor (inklusive programmeraren själv) som läser programmet.

Det finns två typer av kommentarer:

  1. Teckenkombinationen // inleder en kommentar som automatiskt avslutas när raden är slut. Exempel:
    int dice = (int) (6*Math.random() + 1); // Calculate the dice value
  2. Teckenkombinationen /* inleder en kommentar som avslutas med */. En sådan kommentar kan således sträcka sig över flera rader. Exempel:
    /* If you want to write several lines of comments you can do it like this. The comment ends with */

(Observera att vi avråder från att använda svenska tecken i kommentarerna!)

Kommentarerna skall beskriva sådant som inte självklart framgår av koden. Viktigare än kommentarer är att välja bra namn, ha en bra struktur och en vettig layout!

Titta igenom klassen Turtle och se hur kommentarerna är skrivna där.

Övningar

Tänk på att utnyttja de metoder du redan har skrivit!
  1. Skriv en metod i Turtle-klassen, dvs kod som kan användas av en Turtle, som ritar en rektangel. Ge bredd och höjd som parametrar.
    Lägg in några anrop i main-metoden som du lade in i klassen Turtle (alternativt i klassen TestTurtle). Lägg också in anrop till metoder som gör att paddan flyttar sig mellan varje rektangel. Kompilera med och kör med .
  2. Skriv en metod i Turtle-klassen som ritar en (liksidig) triangel. Triangelns sida ges som parameter.
    Fyll på main med anrop till denna metod och kör.
  3. Skriv en metod ritaPentagram som ritar ett pentagram. Ge metoden en parameter som anger storleken (på något sätt).
    Testa även den med anrop från main.

    Ett pentagram ser ut så här:

    Tips: Vinkeln uti spetsarna är 36 grader.


Gå till nästa lektion eller gå tillbaka

Valid CSS!