Lektion 3: Mer om metoder
Syfte: | Öva villkors- och iterationssatser samt på metoder som returnerar värden. Introducera debugging. |
Begrepp som introduceras: |
Metoder med returtyper, if -satsen,
while -satsen.
|
Arbetsform: | Arbeta gärna tillsammans med någon men skriv egen kod. Diskutera med varandra! |
Arbetstid: | 4 timmar |
Redovisning: | Ingen obligatorisk redovisning, men diskutera med handledare om det är något du är osäker på! |
Lite om klassen Turtle och dess invånare
Antag att vi skapar en värld med satsen World w = new World(200,300);
Världen illustreras av den tvådimensionella rektangel som vi då ser på skärmen. Storleken, som vi ger när vi skapar den, mäts i så kallade pixlar (bildpunkter). Det definierar ett koordinatsystem där origo är i rektangelns övre vänstra hörn. X-axeln går på vanligt sätt åt höger men y-axeln går nedåt (vilket är det vanliga sättet när man talar om koordinater på datorskärmar). Det nedre, högra hörnet har alltså koordinaterna (200, 300) i detta exempel.
När vi skapar sköldpaddor (new Turtle(w)
) så berättar vi för dem vilken värld
de tillhör (w
skickas ju som parameter vid skapandet av paddan) och
världen ser då till
att placera ut dem på någon koordinat (verkar vara mitt i världen).
När vi sedan t ex gör move(50)
så flyttas den paddan vi refererar till
en annan koordinat.
Man kan fråga en värld (w) om dess storlek med metoderna getWidth()
och
getHeight()
som i
detta exempel skulle returnera 200 respektive 300.
(I just detta fall vet vi ju var värdena är men man vill kunna skriva kod som
som fungerar generellt.)
Metoder som returnerar värde
De flesta metoder som vi hittills skrivit och använt
(move
, turn
, ritaKvadrat
, ...)
har varit så kallade
void
-metoder.
De gör saker med objekten men returnerar inte något värde.
Det går t ex inte att skriva
int x = t1.move(50).
Metoderna som nämndes i första stycket (getWidth
och
getHeight
) samt metoderna i klassen Math
(Math.sqrt
, Math.sin
, ...)
är exempel på metoder som inte är av void
-typ.
Gemensamt för dessa är att de returnerar ett värde.
Värdet är av typen int
för de två först nämnda och av typen
double
för Math
-metoderna.
Värdet kan tas emot i en variabel eller direkt användas t ex i
en beräkning.
Exempel: | ... int area = w.getHeight()*w.getWidth(); ... double squareRadius = Math.sqrt(area); ... |
Att en metod returnerar något betyder alltså att den levererar ett värde (heltal, flyttal, objektreferens, ...) till den som anropar metoden.
Det är anroparen ("mottagaren") som avgör vad som ska göras med värdet. Det kan t ex sparas i en variabel, användas direkt i en beräkning, skrivas ut eller, till och med, glömmas bort.
För att skriva metoder som returnerar värden måste man
- i metodhuvudet ange värdets typ och
-
i metodkroppen ha en
return
-sats som anger vad värdet ska vara.
Ett första exempel
Antag att vi i klassenWorld
vill ha en metod som returnerar
världens storlek i "kvadratpixlar".
(Vi har inte tidigare skrivit några egna metoder i klassen World
men det är
ingen skillnad a skriva metoder i klassen Turtle
.)
public int area() { int a = this.getWidth()*this.getHeight(); return a; } | Metoden ska returnera ett värde av typen int Först beräknas värdet och sedan returneras det. |
Prova gärna att klistra in detta i World
-klassen och testa i interaktionsrutan!
Anmärkning: Men behöver inte spara resultatet i en variabel. Denna metod skulle kunna ha satsen
return this.getWidth()*this.getHeight();
som enda innehåll.Ett lite större exempel i två varianter
Vi ska titta på en metod som beräknar en paddas avstånd till origo. Den finns här i två varianter. Metoden i den vänstra rutan returnerar resultatet som ett flyttal (double
)
medan metoden i den högra rutan returnerar resultatet som ett heltal (int
).
Koden som skiljer är markerad.
Det är viktigt att typen på värdet i return
-satsen överensstämmer
med typen som står i metodhuvudet!
Eftersom sqrt
-metoden returnerar ett värde av typen double
måste vi i den högra metoden explicit konvertera värdet till int
.
Övning 1
Testa den vänstra metoden double distanceOrigo()
.
Kopiera och klistra in den vänstra metoden längst ned i klassen Turtle
och kompilera.
Skapa en värld i interaktionsrutan och lägg in en padda t1
och anropa metoden så här:
double d = t1.distanceOrigo(); d |
Lagra avståndet i en variabel och titta vad det är. |
double
-variabel
eftersom denna variant av metoden returnerar ett värde av typen double
.
Övning 2
Testa den högra metoden int distanceOrigo()
.
Först måste den vänstra metoden tas bort från klassen Turtle
.
Enklast "tar vi bort" metoden genom att kommentera bort metodens kod.
Gör då så här: I klassen Turtle markera koden för metoden och
högermusklicka och välj Comment Lines(s).
|
![]() |
Resultatet blir då att all kod i metoden kommer att inledas med teckenkombinationen
// och därmed är metoden bortkommenterad.
|
![]() |
Koden kan senare lätt "avkommenteras" genom att markera koden och istället välja Uncomment Line(s).
Nu kan du kopiera och klistra in den högra metoden i klassen Turtle
(t.ex. efter den bortkommenterade metoden) och kompilera.
Skapa en värld och en padda t1
i interaktionsrutan och anropa metoden så här:
int d = t1.distanceOrigo(); d |
Lagra avståndet i en variabel och titta vad det är. |
int
-variabel
eftersom denna variant av metoden returnerar ett värde av typen int
.
Fler metoder i klassen Turtle
Metod | Gör | Exempel |
---|---|---|
int getXPos() |
Returnerar paddans x -koordinat.
|
int x = t1.getXPos(); t1.getXPos() - t2.getXpos(); |
int getYPos() |
Returnerar paddans y -koordinat.
|
|
double distanceTo(int x, int y) |
Returnerar paddans avstånd till punkten (x , y ).
|
|
int getDirection() | Returnerar paddans riktning i grader där 0 är åt höger, 90 nedåt, 180 åt vänster, etc. | |
void setDirection(int direction) |
Ändrar paddans riktning till direction .
|
t1.setDirection(90); t1.setDirection(0); |
void moveTo(int x, int y) | Flyttar paddan till angiven koordinat | t1.moveTo(30, 50); |
Observera:
- Vissa av metoderna ovan returnerar värden (vilka?) medan andra inte gör det
- Det finns metoder utan parametrar, metoder med en parameter och metoder med två parametrar (och med många flera också).
Frågor och övningar
-
Varför behöver metoden
moveTo
parametrar (x och y) men metodengetXPos
inte behöver några parametrar? -
Båda datatyperna
int
ochdouble
förekommer både som returvärden och parametrar. Varför det? -
Skapa en värld
w
med två paddort1
ocht2
. Flytta isär dem en bit.- Testa metoderna som beskrivits ovan
-
Vad händer om man gör de felaktiga (?) anropen
w.getXPos()
respektivet1.getHeight()
? Slutsats? - Går det att flytta en padda utanför världen?
- Skriv den sats (eller de satser) i interaktionsrutan som beräknar avståndet mellan paddorna!
Det finns i själva verket många fler metoder i klassen Turtle
.
Titta gärna på
dokumentationen av Turtle
som hör ihop med sköldpaddan.
if
-satsen
För att kunna skriva kod som väljer mellan olika alternativ så behöver
vi en så kallad villkorssats.
Den vanligaste av dessa är if
-satsen.Läs minilektionerna om
if
-satsen och
logiska uttryck!
Övningar på if
-satsen
I dessa övningar skall du skriva metoder i klassen Turtle
.
-
Skriv en metod
public boolean prison(double fence)
som flyttar paddan till origo om den är mer änfence
pixlar från origo. Använd metodenint distanceOrigo()
som du redan har lagt in ovan. Metoden skall returneratrue
om sköldpaddan flyttats, annarsfalse
. Bekräfta att metoden fungerar, dvs att den returnerartrue
om de flyttar paddan, annars returnerarfalse
. -
Skriv en metod
int distClosestWall()
i klassenTurtle
som returnerar avståndet till den vägg som är närmast dvs det minsta av värden a, b, c och d i figuren nedan.För att lösa detta problem behöver vi veta paddans position och världens storlek.
Paddan vet ju sin egen position med hjälp av metoderna
getXPos()
ochgetYPos()
.Hur får paddan veta höjden och bredden på den värld som paddan är i?
Paddan kan få en referens till den värld som den befinner sig i genom att anropa metoden
getWorld()
som finns i klassenTurtle
.I klassen
World
finns metodernagetWidth()
ochgetHeight()
som returnerar världens bredd respektive höjd.Således kan koden
World myWorld = this.getWorld(); int h = myWorld.getHeight(); int w = myWorld.getWidth();användas för att beräkna höjden och bredden på paddans värld.
Observera att koden inte skapar något nytt värld-objekt! VariabelnmyWorld
är bara en referens till det egna värld-objektet.
En mer erfaren programmerare hoppar vanligen över att föra in en egen variabel för världsreferensen utan skriver i stället ett så kallat "train wreck" (svenska?):int h = this.getWorld().getHeight(); int w = this.getWorld().getWidth();och utelämnar ofta äventhis
framförgetWorld
-anropet. -
Skriv metoden
void bounceWalls(int d)
som flyttar paddan till världens mittpunkt om den är närmare en vägg end
punkter. Testa metoden mot alla fyra väggar!
while
-satsen
För att kunna göra flera saker behöver man kunna skriva kod som upprepas.
Sådan kod kallas för iterationer.Läs minilektionen om
while
-satsen.
Övningar
-
Skriv en metod
drawCircle()
som ritar (approximation till) en cirkel genom att med enwhile
-iteration upprepademove(5)
ochturn(5)
. Vad ska man har för villkor iwhile
-satsen? -
Skriv en metod
void drawCircle(int radius)
i klassenTurtle
som låter paddan gå i (en approximation till) en cirkel med radienradius
. Om paddan kommer närmare världens kanter än 10 punkter skall metoden avbrytas.Tips:
-
Använd metoden
void moveTo(int x, int y)
som flyttar paddan till en absolut position. -
En punkterna på en cirkel med med mittpunkt i (xc, yc) och radie r
ges av
x = xc + r * cos(alfa)
där alfa varierar mellan 0 och 2π. Låt
y = yc + r * sin(alfa)while
-satsen sköta variationen av alfa. -
Tänk på att
Math.sin
ochMath.cos
returnerar av värden av typdouble
medanmoveTo
har parametrar av typint
.
-
Använd metoden
Felsökning
Att leta efter fel i program brukar kallas för avlusning eller, oftast, debugging. DrJava innehåller, liksom de flesta programmeringsmiljöer, ett verktyg för detta som brukar kallas för en debugger.
Prova gärna debuggern genom att gå igenom nedanstående minilektioner:
Gå till nästa lektion eller gå tillbaka
Dölj style3dev.css för att bli av med annoteringarna!