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):
- Skapa mappen
turtleWorld
.På institutionens Linux-datorer gör du så här:-
Öppna filhanteraren genom att välja
Applications> Accessories> Files
Ett fönster visas med namnet Home. -
Högerklicka i det fönstret och välj att skapa en ny mapp med New Folder
och ge namnet
turtleWorld
.
-
Öppna ett terminalfönster genom att välja
Applications> Accessories> Terminal
-
Ge unix-kommandot
mkdir turtleWorld
i det öppnade terminalfönstret.
-
Öppna filhanteraren genom att välja
-
Hämta klasserna
Turtle.java
ochWorld.java
och lägg dem i mappenturtleWorld
(högerklicka och "spara som").
Högerklicka på respektive fil och och välj Save Link As - Starta DoktorJava
-
Öppna de nedladdade filerna med knappen DrJaja-knappen
på
Turtle.java
ochWorld.java
.
Det dyker upp en massa text i den så kallade Definitionsrutan. Ignorera den tills vidare! - 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
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
:
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: |
![]() |
Prova! |
---|
w |
t1 |
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); |
t1
respektive t2
!
Frågor
-
Metoden
turnTo
finns uppenbarligen i två versioner. Vilka? Hur vet man vilken version som används när metoden anropas?Den ena har två parametrar (av typenint
), den andra har en parameter (av typenTurtle
). Det är antal och typ av argumenten som avgör vilken metod som avses. -
Vilken funktion verkar informationen som står inom parentesen ha
när man anropar en metod?
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.
-
Varför skriver man
t1.move(50)
ocht2.move(50)
? Varför räcker det inte med att skrivamove(50)
? Vad händer om du skrivermove(50)
?Det som står till vänster om punkten anger vilket objekt som avses. Om man bara skrivermove(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
-
Skapa en värld
w
med en paddat1
i interaktionsrutan. -
Låt den gå 100 steg, vrida sig 90° medurs, gå 100 steg, vrida sig 90° medurs,
gå 100 steg etc. tills du har fått en kvadrat.
Kom ihåg: Du kan hämta gamla kommandon i interaktionsrutan med uppåtpilen.
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: |
![]() |
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 }
|
|
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.
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:
- Tag bort den gamla världen genom att stänga rutan som världen visas i.
-
Skapa en ny värld
w
. -
Skapa två paddor
t1
ocht2
. - Flytta den ena paddan 100 steg bakåt.
-
Säg åt paddan
t1
att rita en kvadrat genom att skrivat1.ritaKvadrat()
. -
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:-
Metodhuvud. Det är den första raden i metoden
public void ritaKvadrat()
(Egentligen från och medpublic
till första{
- ett metodhuvud kan skrivas på flera rader.) -
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
-
Vad är en metod? Vad är syftet med metoder? Vad skulle hända
om man inte hade några metoder alls?
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.
-
Hur ska en metod se ut?
Se ovan!
- Varför kan man nu skriva
t1.ritaKvadrat()
när att det inte gick förut?Vi har nu lagt till metodenritaKvadrat
i klassenTurtle
. Förut fanns den inte. - Du har placerat metoden
ritaKvadrat
i filenTurtle.java
. Varför skulle det inte fungera om man öppnade filenWorld.java
och placerade den där?FilenWorld.java
innehåller klassenWorld
. Denna klass har inte metoder sommove
,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:
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
-
Kopiera metoden och klistra in den sist i filen
Turtle.java
. - Spara och kompilera ().
-
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 somritaKvadrat()
. - Testa att använda den lokala variabeln
sida
i metodenritaKvadrat()
genom att:-
ändra
this.move(30)
tillthis.move(sida)
. - Spara och kompilera.
- Läs felmeddelandet och förklara i egna ord varför det inte fungerar.
-
ändra
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);
|
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 |
public static void main(String[] args)
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:
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 |
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 klassernaTurtle
ochWorld
. Eftersom enmain
-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ågonmain
-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 imain
-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:
Lite mer information om dett finns i denna minilektion.
Övning
Låtmain
-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:
- Teckenkombinationen
//
inleder en kommentar som automatiskt avslutas när raden är slut. Exempel:int dice = (int) (6*Math.random() + 1); // Calculate the dice value -
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!-
Skriv en metod i
Turtle
-klassen, dvs kod som kan användas av enTurtle
, som ritar en rektangel. Ge bredd och höjd som parametrar.Lägg in några anrop imain
-metoden som du lade in i klassenTurtle
(alternativt i klassenTestTurtle
). Lägg också in anrop till metoder som gör att paddan flyttar sig mellan varje rektangel. Kompilera med och kör med . - 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. -
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ånmain
.Ett pentagram ser ut så här:
Tips: Vinkeln uti spetsarna är 36 grader.
Gå till nästa lektion eller gå tillbaka
Dölj style3dev.css för att bli av med annoteringarna!