228
Methodiek van de Informatica: een lijst van oefeningen Martijn Hemeryck <[email protected]> 20 februari 2007

Oplossingen Methodiek van de Informatica

Embed Size (px)

Citation preview

Page 1: Oplossingen Methodiek van de Informatica

Methodiek van de Informatica: een lijst van

oefeningen

Martijn Hemeryck <[email protected]>

20 februari 2007

Page 2: Oplossingen Methodiek van de Informatica

i

Copyright c© 2007 Martijn Hemeryck. Permission is granted to copy, dis-tribute and/or modify this document under the terms of the GNU Free Docu-mentation License, Version 1.2 or any later version published by the Free Soft-ware Foundation; with no Invariant Sections, no Front-Cover Texts, and noBack-Cover Texts. A copy of the license is included in the section entitled“GNU Free Documentation License”.

Page 3: Oplossingen Methodiek van de Informatica

Voorwoord

Dit boek bevat een aantal oplossingen van de oefeningen van het boek [3] datgebruikt werd in het kader van het vak Methodiek van de Informatica (B-KUL-H01B6A), academiejaar 2005-2006. Destijds was het aanvankelijk voor de mezelfeen handig overzicht van gemaakte oefeningen (evenals ook een leuke manier omLATEX eigen te maken), maar toen naderhand bleek dat het voor andere studen-ten misschien ook wel interessant kon zijn besloot ik hiermee aan te kloppen bijde cursusdienst van VTK. Aangezien deze oplossingen aanvankelijk slechts voormezelf zelf geschreven waren kan het wel zijn dat er wat fouten, hetzij qua vorm,hetzij qua inhoud, in zitten. Gelieve hier dan ook rekening mee te houden bijhet studeren van dit vak, ik neem in geen geval verantwoordelijkheid op voor defouten1. Mochten er trouwens ooit mensen geınteresseerd zijn in de source code,kunnen ze me best contacteren op [email protected] wil ik bij deze ook al de mensen bedanken die mij, hetzij onrecht-streeks, hebben geholpen met het opstellen van deze bundel; nl. de leden vanhet groepje waar ik het practicum heb mee heb mogen doen: K. Herdewyn,R. Hermans en A. Honings. Zonder hen zou ik nooit het inzicht in deze materiehebben verworven dat ik vandaag heb.

1dus, niet komen klagen bij mij als uw examens wat tegen zitten. . .

ii

Page 4: Oplossingen Methodiek van de Informatica

Inhoudsopgave

Voorwoord ii

I Oefeningen uit het handboek 1

1 Objecten en klassen 2

2 Klassedefinities 4

3 Interactie van objecten 17

4 Objecten groeperen 23

5 Geavanceerde werking 36

6 Correct werkende objecten 58

7 Klassen Ontwerpen 74

8 De structuur verbeteren met overerving 100

9 Meer over overerving 107

10 Technieken voor verdere abstractie 112

II Oefeningen uit de oefenzittingen 132

11 Oefenzitting 30-03 13311.1 Tests schrijven . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133

11.1.1 Eerste testklasse . . . . . . . . . . . . . . . . . . . . . . . 13311.1.2 Tweede testklasse . . . . . . . . . . . . . . . . . . . . . . 134

11.2 Correctheidsbewijzen . . . . . . . . . . . . . . . . . . . . . . . . . 13611.2.1 Machtsverheffing . . . . . . . . . . . . . . . . . . . . . . . 136

12 Oefenzitting 20-04 13712.1 Correctheidsbewijzen . . . . . . . . . . . . . . . . . . . . . . . . . 13712.2 Complexiteitsanalyse . . . . . . . . . . . . . . . . . . . . . . . . . 141

iii

Page 5: Oplossingen Methodiek van de Informatica

INHOUDSOPGAVE iv

13 Oefenzitting 27-04 14313.1 Extra oefeningen bij hoofdstuk 8 . . . . . . . . . . . . . . . . . . 143

III Uitwerking andere oefeningen en examens 145

14 Oefeningen op algoritmes 14614.1 Correctheidsbewijzen . . . . . . . . . . . . . . . . . . . . . . . . . 14614.2 Complexiteit van algoritmes . . . . . . . . . . . . . . . . . . . . . 151

15 Examen augustus 2004 155

16 Examen juni 2004 159

17 Examen juni 2003 166

IV Bijlagen 175

A Oefeningen op algoritmen 176

B Uitgewerkt voorbeeldexamen augustus 2004 191

C Een aantal interessante algoritmes 205

D GNU Free Documentation License 2141. APPLICABILITY AND DEFINITIONS . . . . . . . . . . . . . . . 2142. VERBATIM COPYING . . . . . . . . . . . . . . . . . . . . . . . . 2163. COPYING IN QUANTITY . . . . . . . . . . . . . . . . . . . . . . 2164. MODIFICATIONS . . . . . . . . . . . . . . . . . . . . . . . . . . . 2175. COMBINING DOCUMENTS . . . . . . . . . . . . . . . . . . . . . 2186. COLLECTIONS OF DOCUMENTS . . . . . . . . . . . . . . . . . 2197. AGGREGATION WITH INDEPENDENT WORKS . . . . . . . . 2198. TRANSLATION . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2199. TERMINATION . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22010. FUTURE REVISIONS OF THIS LICENSE . . . . . . . . . . . . 220

Page 6: Oplossingen Methodiek van de Informatica

Listings

1.1 Tekenen van een afbeelding met behulp van Picture . . . . . . . 22.1 book-exercise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.2 heater-exercise . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143.1 screen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214.1 club . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255.1 MapTester . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425.2 Responder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435.3 BallDemo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495.4 BoxBall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 535.5 Star Wars name generator . . . . . . . . . . . . . . . . . . . . . 566.1 Testklasse calculator project . . . . . . . . . . . . . . . . . . . . . 666.2 Nieuwe versie calculator project . . . . . . . . . . . . . . . . . . . 686.3 Testklasse voor nieuwe versie calculator project . . . . . . . . . . 727.1 klasse Game . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 797.2 klasse Player . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 837.3 klasse Item . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 907.4 klasse Command . . . . . . . . . . . . . . . . . . . . . . . . . . . 917.5 klasse CommandWords . . . . . . . . . . . . . . . . . . . . . . . . 937.6 klasse Room . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 947.7 klasse Parser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 978.1 een voorbeeldlijstje voor het project DoME . . . . . . . . . . . . 1008.2 klasse VideoGame . . . . . . . . . . . . . . . . . . . . . . . . . . 1018.3 klasse Person . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1038.4 klasse Student . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1048.5 klasse Docent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1059.1 klasse CD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1079.2 klasse Video . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1089.3 klasse MagicRoom uit zuul-better . . . . . . . . . . . . . . . . . . 1099.4 oef 9.17 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11110.1 klasse Animal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11410.2 klasse PopulationGenerator . . . . . . . . . . . . . . . . . . . . . 11810.3 klasse Animal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12110.4 klasse Fox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12510.5 klasse Rabbit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12912.1 stramien correctheidsbewijs . . . . . . . . . . . . . . . . . . . . . 13712.2 correctheidsbewijs bij macht . . . . . . . . . . . . . . . . . . . . . 13712.3 correctheidsbewijs bij grootste gemene deler . . . . . . . . . . . . 13812.4 correctheidsbewijs bij bubblesort . . . . . . . . . . . . . . . . . . 13912.5 sorteeralgoritme en complexiteit . . . . . . . . . . . . . . . . . . 141

v

Page 7: Oplossingen Methodiek van de Informatica

LISTINGS vi

13.1 klasse Rechthoek . . . . . . . . . . . . . . . . . . . . . . . . . . . 14314.1 correctheidsbewijs bij bubbleSort . . . . . . . . . . . . . . . . . . 14714.2 sorteeralgoritme en complexiteit . . . . . . . . . . . . . . . . . . 151C.1 klasse Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . 205

Page 8: Oplossingen Methodiek van de Informatica

Deel I

Oefeningen uit hethandboek

1

Page 9: Oplossingen Methodiek van de Informatica

Hoofdstuk 1

Objecten en klassen

Oefening 1.1 Zie blz. 4. Dit doe je het best via de interface van BlueJ zelf.

Oefening 1.2 Als je tweemaal moveDown uitvoert zal de cirkel 40 pixels naarbeneden verschoven zijn. Eenmaal deze methode uitvoeren zorgt er nl. voor dathet object 20 pixels naar beneden wordt verschoven. De methode makeInvisiblezorgt er op haar beurt dan voor dat de cirkel niet meer zichtbaar is.

Oefening 1.3 De methode moveHorizontal zal een cirkel de opgegeven afstandin pixels naar rechts ten opzichte van de oorspronkelijke positie verplaatsen. Omnaar links te verplaatsen geef je gewoon -70 mee als argument voor de methode.

Oefening 1.4 Wanneer je simpelweg ”rood” zou schrijven, wat niet volgensdeze methode herkend wordt, krijg je automatisch zwart terug als kleur voor decirkel. Als je daarentegen ”red” zou meegeven als argument zal je zien de kleurinderdaad nu rood is.

Oefening 1.5 Zelfde antwoord als oefening 1.4.(blz. 2). Bij het invoeren vaneen ongeldige string wordt de kleur standaard zwart gekozen.

Oefening 1.6 Zonder aanhalingstekens wordt de ingevoerde kleur niet alsstring herkend. Er zal dus niets gebeuren. BlueJ heeft op dit gebied een vei-ligheid die het invoeren van ongeldige argumenten tegengaat en zal dus vragenom opnieuw een geldig argument door te geven. Ook bij het zelf schrijven vansoftware is dit trouwens een zeer belangrijk gegeven.

Oefening 1.11 De klasse Picture maakt gebruik van objecten uit de klassenvan het voorgaande shapes project, nl. objecten uit de klassen Circle, Squareen Triangle. Dit blijkt ook duidelijk uit de sourcecode (oftewel broncode):

Listing 1.1: Tekenen van een afbeelding met behulp van Picture{

pr i va t e Square wa l l ;p r i va t e Square window ;p r i va t e Tr iang l e r oo f ;

2

Page 10: Oplossingen Methodiek van de Informatica

HOOFDSTUK 1. OBJECTEN EN KLASSEN 3

p r i va t e C i r c l e sun ;}

Oefening 1.13 Dat is uiteraard de methode Draw().

Oefening 1.27 Bij sommige gegevens zijn meerdere types mogelijk. We gevenze hier onder weer.

• 0: byte, short, int , long

• ’ hallo ’ : String

• 101: short, int , long

• −1: byte, short, int , long

• WAAR: boolean (hoewel in JAVA alleen true of false herkend wordt)

• ’33’ : String

• 3.1415: float , double

p r i va t e St r ing name ;

pub l i c void send ( St r ing param)

pub l i c i n t average ( i n t param1 , i n t param2 )

Oefening 1.31 Dit kan je op verschillende manieren bekijken:

• Als object: het maakt deel uit van de grotere verzameling van boeken,wat op haar beurt weer een kleinere klasse zou kunnen zijn van een klasseliteratuur.

• Als klasse: een boek op zich kunnen we zien als een klasse voor bijvoor-beeld hoofdstuk-objecten of bijvoorbeeld bladzijde objecten.

De keuze van opdeling hangt af van de toepassing.

Oefening 1.32 Een object kan tot meerdere klassen behoren door bijvoor-beeld overerving.

Page 11: Oplossingen Methodiek van de Informatica

Hoofdstuk 2

Klassedefinities

Oefening 2.2 Het project naive-ticket-machine heeft geen methode die dewaarde van total terug op 0 zet. Het totaal van de automaat staat dan ook opde totale hoeveelheid geld die er werd ingestoken.

Oefening 2.3

• De automaat geeft het bedrag dat teveel werd ingeworpen niet terug.

• De automaat drukt ook kaartjes af als er niet genoeg geld is ingeworpen.

Oefening 2.5 Het kaartje ziet er anders uit, de prijs van het kaartje is nu deprijs die via de constructor werd ingevoerd.

Oefening 2.6

• Omhulsel Student

pub l i c c l a s s Student { }

• Omhulsel LabClass

pub l i c c l a s s LabClass { }

Oefening 2.7 Enkel de eerste schrijfwijze is de juiste.

Oefening 2.8 Het is mogelijk om dit weg te laten, maar het is best dit niette doen teneinde verwarring te voorkomen.

Oefening 2.9

• velden:

p r i c e ba lance t o t a l

• constructors:

pub l i c TicketMachine ( i n t TicketCost )

4

Page 12: Oplossingen Methodiek van de Informatica

HOOFDSTUK 2. KLASSEDEFINITIES 5

• methodes:

g e tPr i c e ( )getBalance ( )insertMoney ( )p r in tT i cke t ( )

Oefening 2.10

• De constructor heeft geen return type opgegeven.

• De naam van de constructor heeft dezelfde naam als de klasse (incl. dehoofdletter).

Oefening 2.11

• int

• Student

• Server

Oefening 2.12

• alive

• tutor

• game

Oefening 2.13 De volgorde is belangrijk; in een andere volgorde lukt compilenniet?

Oefening 2.14 Velddeclaraties moeten altijd worden afgesloten door een pun-tkomma.

Oefening 2.15 private int status ;

Oefening 2.16 Klasse Student

Oefening 2.17 Twee parameters, n van het type String en n van het typedouble.

Oefening 2.18 Waarschijnlijk het type String aangezien er veel gegevens inde vorm van tekst zal opgevraagd worden.

pub l i c Pet ( S t r ing petsName ){

name = petsName ;}

Page 13: Oplossingen Methodiek van de Informatica

HOOFDSTUK 2. KLASSEDEFINITIES 6

Oefening 2.20 De regel int price = ticketCost;. Het type wordt bepaald inde velden, buiten deze methode.

Oefening 2.21 Er is geen verschil tussen deze twee accessormethodes.

Oefening 2.22 ’Hoeveel is de hoeveelheid geld die ik momenteel al in deautomaat heb ingeworpen.’

Oefening 2.23 Neen, de naam van de methode wijzigen zal alleen een effecthebben op de leesbaarheid van de code.

pub l i c i n t getTota l ( ){

re turn t o t a l ;}

Oefening 2.25 In de header van de methode staat een return type. Er wordtdan ook verwacht dat er gegevens van het return type worden teruggegeven doorde methode.

Oefening 2.26 Het return type: getPrice() geeft een int terug, printTicketheeft geen return type.

Oefening 2.27 Geen return statements, beide van type void.

Oefening 2.29 Aan het return type.

pub l i c void s e tP r i c e ( i n t t i c k e tCos t ){

p r i c e = t i ck e tCos t ;}

pub l i c void i n c r e a s e ( i n t po in t s ){

s c o r e += po in t s ;}

Page 14: Oplossingen Methodiek van de Informatica

HOOFDSTUK 2. KLASSEDEFINITIES 7

/∗∗∗ Verlaag p r i c e met het gegeven bedrag .∗ @param amount Gegeven kor t ing ( p o s i t i e f bedrag )∗/

pub l i c void d i s count { i n t amount}{

p r i c e −= amount ;}

pub l i c void prompt ( ){

System . out . p r i n t l n ( ”Werp de gepaste hoevee lhe id ge ldin . ” ) ;

}

pub l i c void showPrice ( ){

System . out . p r i n t l n ( ”De p r i j s van een kaa r t j e i s ” +p r i c e + ” cent . ” ) ;

}

Oefening 2.35 Verschillende output omdat de waarde van price in de tweegevallen verschillend is.

Oefening 2.36 # price cent.

Oefening 2.37 Zie oef 2.36

Oefening 2.38 Neen, eigenlijk prijs zit er niet in; ”price” wordt herkend alszijnde een ander stuk van de print.

pub l i c TicketMachine ( ){

p r i c e = 1000 ;ba lance = 0 ;t o t a l = 0 ;

}

Page 15: Oplossingen Methodiek van de Informatica

HOOFDSTUK 2. KLASSEDEFINITIES 8

pub l i c void empty ( ){

t o t a l = 0 ;}

Oefening 2.41 Zie oefeningen 2.29 - 2.30.

Oefening 2.42

• Constructor met parameter (de originele constructor):

pub l i c TicketMachine ( i n t t i c k e tCos t ){

p r i c e = t i ck e tCos t ;ba lance = 0 ;t o t a l = 0 ;

}

• Constructor zonder parameter (met prijs initieel op waarde 200 ingesteld:

pub l i c TicketMachine ( ){

p r i c e = 200 ;ba lance = 0 ;t o t a l = 0 ;

}

Oefening 2.43 Wanneer er een verkeerd bedrag wordt ingeworpen wordt erenkel een foutmelding weergegeven. Een verkeerd bedrag (zoals een negatiefbedrag) zal niets veranderen aan de waarde van het veld balance in de methodeinsertMoney().

Oefening 2.44 Door >= in plaats van == te gebruiken, zullen we nu ookbedragen gelijk aan 0 mogen inwerpen. Dit verandert niets aan de waardevan het veld balance, maar zorgt er wel voor dat er geen foutmelding wordtweergegeven bij een nul-bedrag.

Oefening 2.45 De boolean werd gebruikt om het al dan niet zichtbaar zijnvan het object aan te geven (veld isVisible ). Aangezien dat enkel maar waarof niet waar kan zijn, is dit een juiste keuze.

Oefening 2.46 Bij de methode van code 2.8 wordt de waarde van balancegelijkgesteld aan het geld dat er nog overschiet nadat het kaartje is afgedrukt.Bij de versie van code 2.1 wordt balance gelijkgesteld aan 0. Versie 2.8 is beterin die zin dat het een mogelijkheid biedt om het teveel aan geld later nog terugte geven.

Page 16: Oplossingen Methodiek van de Informatica

HOOFDSTUK 2. KLASSEDEFINITIES 9

Oefening 2.47 Neen, de voorwaarde voor een kaartje af te drukken is

balance >= price

Dit betekent dus dat binnen deze methode balance nooit negatief gaat zijn. Metandere woorden: als er niet genoeg geld is ingeworpen zal er geen kaartje afge-drukt worden en zal de verandering van het veld balance ook niet doorgevoerdworden.

p r i c e ∗ di scount = sav ing ;

t o t a l / count = mean ;

i f ( p r i c e > budget ) {System . out . p r i n t l n ( ”Te duur” ) ;

} e l s e {System . out . p r i n t l n ( ” Pr e c i e s goed” ) ;

}

i f ( p r i c e > budget ) {System . out . p r i n t l n ( ”Te duur , budget bedraagt s l e c h t s

” + budget ) ;} e l s e {

System . out . p r i n t l n ( ” Pr e c i e s goed” ) ;}

Oefening 2.53 Omdat je hier gewoon de waarde van balance gelijk stelt aan0 en dat dan terug geeft. In het andere geval zetten we de waarde in een lokalevariable amountToRefund, geven deze terug en dan pas zetten we de waardevan balance op 0.

Oefening 2.54 Deze versie kan niet gecompileerd worden aangezien het state-ment dat zegt wat er met het veld balance moet gebeuren na het return state-ment staat. Dit moet er dus voor staan.

pub l i c i n t emptyMachine ( ){

i n t totalAmount ;totalAmount = t o t a l ;t o t a l = 0 ;re turn totalAmount ;

}

Page 17: Oplossingen Methodiek van de Informatica

HOOFDSTUK 2. KLASSEDEFINITIES 10

Vergelijk met methode refundBalance.

Oefening 2.56 We kunnen deze methode als een combinatie van accessor/-mutator zien:

• Accessor: de waarde van total wordt weergegeven.

• Mutator: de waarde van total wordt op 0 gezet.

Oefening 2.57 Aan te passen in de methode printTicket:

i n t amountLeftToPay = pr i c e − balance ;

i f ( amountLeftToPay <= 0){

}

Oefening 2.58 Een mogelijk oplossing is de volgende: we stellen dat er tweetypes kaartjes zijn, eerste en tweede klasse met respectievelijk als prijs 200 en100. Volgende zaken worden dan toegevoegd:

• Velden:

// Type o f t i c k e t to be pr in ted : here we choose onlytwo types .

p r i va t e i n t type ;

• Methode setType om het type in te stellen (hier slechts 1 of 2):

pub l i c void setType ( i n t inputType ){

i f ( inputType == 1 | | inputType == 2){

type = inputType ;} e l s e{

System . out . p r i n t l n ( ”Ongeldig type , probeeropnieuw . ” ) ;

}setPriceWithType ( ) ;

}

• Methode setPriceWithType om de prijs in te stellen voor ieder type (1:200, 2: 100):

pub l i c void setPriceWithType ( ){

i f ( type == 1){

Page 18: Oplossingen Methodiek van de Informatica

HOOFDSTUK 2. KLASSEDEFINITIES 11

//Voor type 1 : p r i j s bedraagt 200p r i c e = 200 ;

} e l s e{

//Voor type 2 : p r i j s bedraagt 100p r i c e = 100 ;

}}

Het mag duidelijk zijn dat dit maar n mogelijk oplossing is voor dit probleem.Echt optimaal is ze ook niet, want stel dat we een derde type zouden willenschrijven, dan moet er toch nog veel veranderen aan de code.

Oefening 2.60 Henr557

Oefening 2.61 Er wordt een foutmelding weergegeven: StringIndexOutOfBoundsException. Dit betekent dat de String name te kort is om de methode getLoginName optoe te passen.

Oefening 2.62 De nieuwe constructor:

pub l i c Student ( S t r ing fullName , S t r ing studentID ){

i f ( fullName . l ength ( ) >= 4){

name = fullName ;} e l s e{

System . out . p r i n t l n ( ”Foutmelding” ) ;}

i f ( studentID . l ength ( ) >= 3){

id = studentID ;} e l s e{

System . out . p r i n t l n ( ”Foutmelding” ) ;}

c r e d i t s = 0 ;}

Oefening 2.63 De beste oplossing is hier gebruik maken van 2 lokale vari-abelen printName en printId. Dit doen we omdat als we alle mogelijkhedenafgaan we 4 if-statements zouden moeten gebruiken. In dit voorbeeld was datnog doenbaar geweest, voor meer variabelen wordt dit te complex en zal hetprogramma ook trager gaan werken.

Page 19: Oplossingen Methodiek van de Informatica

HOOFDSTUK 2. KLASSEDEFINITIES 12

pub l i c S t r ing getLoginName ( ){

St r ing printName ;S t r ing p r i n t Id ;

i f (name . l ength ( ) < 4){

printName = name ;} e l s e{

printName = name . sub s t r i ng (0 , 4 ) ;}

i f ( id . l ength ( ) < 3){

pr in t Id = id ;} e l s e{

pr in t Id = id . sub s t r i ng (0 , 3 ) ;}

re turn printName + pr in t Id ;}

Oefening 2.64 - 2.71 De code voor deze oefeningen:

Listing 2.1: book-exercise/∗∗∗ A c l a s s that maintains in fo rmat ion on a book .∗ This might form part o f a l a r g e r app l i c a t i o n such∗ as a l i b r a r y system , f o r i n s t anc e .∗∗ @author Mart i jn Hemeryck∗ @version 0 .1 2006−03∗/

c l a s s Book{

// The f i e l d s .p r i va t e St r ing author ;p r i va t e St r ing t i t l e ;p r i va t e i n t pages ;p r i va t e St r ing refNumber ;p r i va t e i n t borrowed ;

/∗∗∗ Set the author and t i t l e f i e l d s when t h i s ob j e c t∗ i s cons t ruc ted .∗/

Page 20: Oplossingen Methodiek van de Informatica

HOOFDSTUK 2. KLASSEDEFINITIES 13

pub l i c Book ( St r ing bookAuthor , S t r ing bookTit le , i n tnumberPages )

{author = bookAuthor ;t i t l e = bookTit l e ;pages = numberPages ;refNumber = ”” ;borrowed = 0 ;

}

pub l i c S t r ing getAuthor ( ){

re turn author ;}

pub l i c S t r ing g e tT i t l e ( ){

re turn t i t l e ;}

pub l i c void printAuthor ( ){

System . out . p r i n t l n ( author ) ;}

pub l i c void p r i n tT i t l e ( ){

System . out . p r i n t l n ( t i t l e ) ;}

pub l i c i n t getPages ( ){

re turn pages ;}

pub l i c void p r i n tDe t a i l s ( ){

System . out . p r i n t l n ( ” T i t e l : ” + t i t l e + ” , Auteur :” + author + ” , Aantal pagina ’ s : ” + pages +

” , Aantal maal u i t g e l e end : ” + borrowed ) ;

i f ( refNumber . l ength ( ) > 0){

System . out . p r i n t l n ( ”Referentienummer : ” +refNumber ) ;

} e l s e{

System . out . p r i n t l n ( ” zzz ” ) ;}

Page 21: Oplossingen Methodiek van de Informatica

HOOFDSTUK 2. KLASSEDEFINITIES 14

}

pub l i c void setRefNumber ( S t r ing r e f ){

i f ( r e f . l ength ( ) >= 3){

refNumber = r e f ;} e l s e{

System . out . p r i n t l n ( ”Verkeerd referent ienummer. Probeer opnieuw . ” ) ;

}}

pub l i c S t r ing getRefNumber ( ){

re turn refNumber ;}

pub l i c void borrow ( ){

borrowed++;}pub l i c i n t getBorrowed ( ){

re turn borrowed ;}

}

Oefening 2.72 - 2.73 De code voor deze twee oefeningen:

Listing 2.2: heater-exercise

/∗∗∗ Write a d e s c r i p t i o n o f c l a s s Heater here .∗∗ @author Ruben & Marti jn∗ @version 2006−02−20∗/

pub l i c c l a s s Heater{

// in s t anc e v a r i a b l e s − r ep l a c e the example belowwith your own

pr i va t e i n t temperature ;p r i va t e i n t min ;p r i va t e i n t max ;p r i va t e i n t increment ;

/∗∗

Page 22: Oplossingen Methodiek van de Informatica

HOOFDSTUK 2. KLASSEDEFINITIES 15

∗ Constructor f o r ob j e c t s o f c l a s s Heater∗/

pub l i c Heater ( i n t minTemp , i n t maxTemp){

// i n i t i a l i s e i n s t anc e v a r i a b l e stemperature = 15 ;min = minTemp ;max = maxTemp;increment = 0 ;

}

/∗∗∗ I n c r e a s e the temperature with value increment∗ un t i l the maximum i s reached∗/

pub l i c void warmer ( ){

i f ( temperature <= max){

temperature += increment ;}

}

/∗∗∗ Decrease the temperature with value increment∗ un t i l the minimum i s reached∗/

pub l i c void c o o l e r ( ){

i f ( temperature >= min){

temperature −= increment ;}

}

/∗∗∗ Accessor f o r the temperature∗ @return i n t temperature The temperature∗/

pub l i c i n t getTemperature ( ){

re turn temperature ;}

/∗∗∗ Sets the increment f o r i n c r e a s i n g / dec r ea s ing the∗ temperature∗ @param in t inputIncrement The value used to

i n c r e a s e / dec r ea s e the temperature∗/

Page 23: Oplossingen Methodiek van de Informatica

HOOFDSTUK 2. KLASSEDEFINITIES 16

pub l i c void set Increment ( i n t inputIncrement ){

i f ( inputIncrement >= 0){

increment = inputIncrement ;}

}}

Page 24: Oplossingen Methodiek van de Informatica

Hoofdstuk 3

Interactie van objecten

Oefening 3.2 Klassediagram wijzigt bij het aanmaken van nieuwe klassen.

Oefening 3.3 Objectdiagram wijzigt bij het aanmaken van nieuwe objecten.

Oefening 3.4 private Instructor tutor

Oefening 3.6 Als de je een ongeldige waarde ingeeft zal er in feite nietsgebeuren. De methode wordt dan ook niet uitgevoerd. Beter zou bijvoorbeeldzijn wanneer er bij een ongeldige waarde een print naar het scherm zou gemaaktworden met de vermelding dat de ingevoerde waarde ongeldig is.

Bijvoorbeeld:

e l s e{

System . out . p r i n t l n ( ”Ongeldige waarde , probeer opnieuw. ” ) ;

}

Oefening 3.7 Het argument van de methode (replacementValue) kan nooitgelijk zijn aan 0.

Oefening 3.8 Er zal maar slechts voldaan moeten worden aan n van de tweetesten - het programma werkt dan ook anders.

! f a l s e (34 != 33) && ! f a l s e

(A && B) | | ! (A && B)

A && !B

17

Page 25: Oplossingen Methodiek van de Informatica

HOOFDSTUK 3. INTERACTIE VAN OBJECTEN 18

i f ( a == b){

re turn true ;}

Oefening 3.13 Deze methode is enkel bedoeld te werken voor normale waar-den van een uurwerk. Vanaf waarden boven de 99 zal de methode nog welwerken maar zal de klok als geheel niet meer juist functioneren.

Oefening 3.14 Neen, er is geen verschil. Beide regels zorgen ervoor dat valueals een String-object zal beschouwd worden.

Oefening 3.15 De modulo-operator geeft de rest terug van een Euclidischedeling.

Oefening 3.16 8 % 3 = 2

Oefening 3.17 Mogelijke resultaten: 0,1,2,3,4

Oefening 3.18 Mogelijke resultaten: 0,1,. . . ,m-1

Oefening 3.19 Vanaf het moment dat de 60 min. overschreden worden (vanafdat de waarde limit overschreden wordt): rest van de deling is gelijk aan 0. If-statement in de methode timeTick() is dan true en de waarde van de uren zalmet 1 verhoogd worden door de methode increment() hier dan toe te passen.

pub l i c void increment ( ){

i f ( va lue < l im i t ){value++;} e l s e{value = 0 ;}

}

Oefening 3.22 De tijd staat ingesteld op 00:00. Waarschijnlijk om een stan-daard tijd te definieren. Wat de standaard is, maakt niet uit.

Oefening 3.23 De methode tick telt telkens maar 1 minuut bij, dus 60 keer.Via setTime(int hour, int minute) zou het mogelijk moeten zijn om de tijdrechtstreeks op 01:00 in te stellen.

Page 26: Oplossingen Methodiek van de Informatica

HOOFDSTUK 3. INTERACTIE VAN OBJECTEN 19

Oefening 3.24 Header van een mogelijke constructor:

pub l i c Editor ( S t r ing fi leName , i n t g e t a l )

p r i va t e Rechthoek window ;

pub l i c Rechthoek ( i n t param1 , i n t param2 ){

window = new Rechthoek (param1 , param2 ) ;}

Oefening 3.26 Deze constructor maakt een nieuw ClockDisplay object aanmet een bepaalde tijd al ingesteld, waarbij deze tijd wordt ingesteld door deparameters die mee worden gegeven aan de constructor. Als erg geen parametersworden meegegeven wordt de andere constructor gebruikt (overloading).

Oefening 3.27 De methode updateDisplay wordt niet aangeroepen in detweede constructor omdat in deze methode de methode setTime wordt opgeroependie ook verwijst naar updateDisplay.

p r i n t ( ”bestand . txt ” , t rue ) ;ge tSta tus (5 ) ;

Oefening 3.29 Een mogelijke oplossing is volgende aanpassingen door te vo-eren.

pub l i c ClockDisplay ( ) ; //Aanpassing cons t ruc to r{

hours = new NumberDisplay (12) ;minutes = new NumberDisplay (60) ;updateDisplay ( ) ;

}

pub l i c void timeTick ( ) {minutes . increment ( ) ;i f ( minutes . getValue ( ) == 0)

{hours . setValue (12) ;

}updateDisplay ( ) ;

}

Page 27: Oplossingen Methodiek van de Informatica

HOOFDSTUK 3. INTERACTIE VAN OBJECTEN 20

Oefening 3.30 Deze methode is beter omdat de interne werking van de klokhetzelfde blijft. We veranderen enkel de methode updateDisplay() omdat dezein feite de methode is waar we gebruik van maken om voor de gebruiker visueleoutput te hebben. Dit is echter slechts n van de vele manieren om dit te doen.

p r i va t e void updateDisplay ( ){

i f ( hours . getValue == 0){

//De waarde voor de uren voor 00 :00d i s p l a yS t r i n g = ” 12 : ” + minutes . getDisplayValue ( )

+ ”am” ;

} e l s e{

i f ( hours . getValue ( ) > 12){

//De waarden voor de uren van 13 :00 to t enmet 23 :00

d i s p l a yS t r i n g = hours . getDisp layValue ( ) − 12+ ” : ” +

minutes . getDisp layValue ( ) + ”pm” ;} e l s e{

//De waarden voor de uren van 01 :00 to t enmet 12 :00

d i s p l a yS t r i n g = hours . getDisp layValue ( ) + ” : ”+

minutes . g e tD i sp layVa l i e ( )+ ”am” ;}

}}

Oefening 3.36 - 3.37 In het geval dat er geen berichten zijn zullen er in deeerste stappen (if-statement) niets afgeprint worden, in het andere geval wordter het statement No new mail. afgeprint.

Oefening 3.38 Wanneer er een aanroep naar een andere methode wordtgedaan, zal de debugger bij gebruik van ”step into”de implementatie van diemethode laten zien.

Oefening 3.39 In plaats van de te verwijzen naar de implementatie van demethode, wordt er hier een verwijzing gemaakt naar de implementatie van deconstructor.

Oefening 3.43 Volgende aanpassingen zijn nodig:

• De klasse MailItem

– velden: private String subject;

Page 28: Oplossingen Methodiek van de Informatica

HOOFDSTUK 3. INTERACTIE VAN OBJECTEN 21

– constructor:

pub l i c MailItem ( St r ing from , St r ing to , S t r ingmessage , S t r ing

sub j e c t ){

t h i s . from = from ;t h i s . to = to ;t h i s . message = message ;t h i s . s ub j e c t = sub j e c t ;

}

– accessor methode:

pub l i c S t r ing ge tSub jec t ( ){

re turn sub j e c t ;}

– print methode:

pub l i c void p r in t ( ){

System . out . p r i n t l n ( ”From : ” + from ) ;System . out . p r i n t l n ( ”To : ” + to ) ;System . out . p r i n t l n ( ”Message : ” + message ) ;System . out . p r i n t l n ( ” Subject : ” + sub j e c t ) ;

}

• De klasse MailClient, de methode sendMessage():

pub l i c void sendMessage ( S t r ing to , S t r ing message ,S t r ing sub j e c t )

{MailItem mess = new MailItem ( user , to , message ,

sub j e c t ) ;s e r v e r . post ( mess ) ;

}

Listing 3.1: screen

/∗∗∗ Ex . 3 .44∗∗ @author Mart i jn Hemeryck∗ @version 2006−02−23∗/

pub l i c c l a s s Screen{

// Reso lut ion xp r i va t e i n t xRes ;

Page 29: Oplossingen Methodiek van de Informatica

HOOFDSTUK 3. INTERACTIE VAN OBJECTEN 22

// Reso lut ion yp r i va t e i n t yRes ;

// Boolean f o r methodpr i va t e boolean i nv e r t ;

/∗∗∗ Constructor f o r ob j e c t s o f c l a s s Screen∗/

pub l i c Screen ( i n t xRes , i n t yRes ){

// i n i t i a l i s e i n s t anc e v a r i a b l e st h i s . xRes = xRes ;t h i s . yRes = yRes ;

}

/∗∗∗ Returns the number o f p i x e l s∗/

pub l i c i n t numberOfPixels ( ){

re turn xRes ∗ yRes ;}

/∗∗∗ Clears the s c r e en i f the argument i s t rue∗ and i f the number o f p i x e l s exceeds the value∗ o f 2 m i l l i o n .∗/

pub l i c void c l e a r ( boolean i nv e r t ){

i f ( numberOfPixels ( ) < 2000000){

xRes = 0 ;yRes = 0 ;

}}

}

Page 30: Oplossingen Methodiek van de Informatica

Hoofdstuk 4

Objecten groeperen

Oefening 4.2 Als de collectie n objecten bevat zal de methode size () nteruggeven als int.

Oefening 4.3 System.out.println(items.get(4)) ;

Oefening 4.4 Het indexnummer is dan 14 (0,1,2,...14).

Oefening 4.5 Vergelijkbaar met methode storeNote().

Oefening 4.6 Gebruik maken van de methode remove() uit het package.

Oefening 4.7 Indexnummer 5; slechts het verwijderen van het element opindex 0 heeft een invloed op het object op indexnummer 6.

Oefening 4.8 Methode showNote() overnemen en ipv get() remove() toepassen.(Uiteraard niet afprinten).

Oefening 4.9 Alle objecten als String terug:public String listAllNotes ()Alle objecten afprinten op het scherm:public void listAllNotes ()Deze methode zou dan geen parameters nodig hebben.

Oefening 4.10 Als we n nota’s hebben zouden we n van deze statementsnodig hebben om ze allemaal te schrijven. Dit is veel te veel werk, oplossen metbehulp van lussen (while, do-while, if,...).

pub l i c void l i s tNo t e s ( ){

i n t index =0;i n t no t e sS i z e = notes . s i z e ( ) ;

whi l e ( index < no t e sS i z e )

23

Page 31: Oplossingen Methodiek van de Informatica

HOOFDSTUK 4. OBJECTEN GROEPEREN 24

{System . out . p r i n t l n ( ( index+1) + ” : ” + notes . get (

index ) ) ;index++;

}}

pub l i c void showNote ( i n t noteNumber ){

noteNumber = noteNumber − 1 ;

i f ( noteNumber < 0) {// This i s not a va l i d note number , so do nothing

.System . out . p r i n t l n ( ” Inva l i d note number . P lease

ente r va l i d number . ” ) ;}e l s e i f ( noteNumber < numberOfNotes ( ) ) {

// This i s a va l i d note number , so we can pr in ti t .

System . out . p r i n t l n ( notes . get ( noteNumber ) ) ;}e l s e {

// This i s not a va l i d note number , so do nothing.

System . out . p r i n t l n ( ” Inva l i d note number . P leaseente r va l i d number” ) ;

}}

pub l i c void removeNote ( i n t noteNumber ){

noteNumber = noteNumber − 1 ;

i f ( noteNumber < 0) {// This i s not a va l i d note number , so do nothing

.System . out . p r i n t l n ( ” Inva l i d note number . P lease

ente r va l i d number . ” ) ;}e l s e i f ( noteNumber < numberOfNotes ( ) ) {

// This i s a va l i d note number , so we can pr in ti t .

notes . remove ( noteNumber ) ;}e l s e {

// This i s not a va l i d note number , so do nothing.

Page 32: Oplossingen Methodiek van de Informatica

HOOFDSTUK 4. OBJECTEN GROEPEREN 25

System . out . p r i n t l n ( ” Inva l i d note number . P leaseente r va l i d number . ” ) ;

}}

Simpele System.out.println(”Error message”).

Oefening 4.15 In print-statement indexnummer toevoegen. Zie oefening 4.11

Oefening 4.16 notes. size () vervangen door een lokale variabele, bijvoorbeeldmet de naam notesSize;

i n t no t e sS i z e = notes . s i z e ( ) ;

.

Oefening 4.17 Bij de lokale variabele index 1 optellen. Van de lokale variablenoteNumber 1 aftrekken.

Oefening 4.18 While-lussen blijft over zichzelf itereren zolang de test trueteruggeeft. If-statements worden slechts n maal doorgenomen.

Listing 4.1: clubimport java . u t i l . ArrayList ;import java . u t i l . I t e r a t o r ;

/∗∗∗ Store d e t a i l s o f c lub memberships .∗∗ @author Mart i jn Hemeryck∗ @version 2006−02−21∗/

pub l i c c l a s s Club{

// Ex . 4 .19p r i va t e ArrayList members ;

/∗∗∗ Constructor f o r ob j e c t s o f c l a s s Club∗/

pub l i c Club ( ){

members = new ArrayList ( ) ;}

/∗∗∗ Add a new member to the c lub ’ s l i s t o f members .∗ @param member The member ob j e c t to be added .

Page 33: Oplossingen Methodiek van de Informatica

HOOFDSTUK 4. OBJECTEN GROEPEREN 26

∗ Ex . 4 .21∗/

pub l i c void j o i n (Membership member){

members . add (member) ;}

/∗∗∗ @return The number o f members (Membership ob j e c t s )

in∗ the c lub .∗ Ex . 4 .20∗/

pub l i c i n t numberOfMembers ( ){

re turn members . s i z e ( ) ;}

/∗∗∗ r e tu rn s the number o f members j o i n ed in a month .∗ @param month The month in which ob j e c t s were added

.∗ Ex . 4 .30∗/

pub l i c i n t joinedInMonth ( i n t month){

// I n i t i a l i s e l o c a l v a r i ab l e which w i l l be usedas a counter f o r members in a month .

i n t membersInMonth = 0 ;

i f (month >= 1 && month <= 12){

I t e r a t o r i t = members . i t e r a t o r ( ) ;

whi l e ( i t . hasNext ( ) ){

Membership member = (Membership ) i t . next( ) ;

i f (member . getMonth ( ) == month){

membersInMonth++;}

}re turn membersInMonth ;

} e l s e{

re turn membersInMonth = 0 ;}

}

Page 34: Oplossingen Methodiek van de Informatica

HOOFDSTUK 4. OBJECTEN GROEPEREN 27

/∗∗∗ Ex 4.31∗ Don ’ t use an i t e r a t o r here !∗/

pub l i c ArrayList purge ( i n t month , i n t year ){

i f (month < 1 | | month > 12){

re turn nu l l ;}

ArrayList r e s u l t = new ArrayList ( ) ;i n t index = members . s i z e ( ) ;

whi l e ( index > 0) ;{

Membership m = (Membership ) members . get (index−1) ;

i f (m. getMonth ( ) == month){

r e s u l t . add (m) ;members . remove ( index−1) ;

}re turn r e s u l t ;

}}

}

Lot s e l e c t edLo t = ( Lot ) l o t s . get ( lotNumber − 1) ;

Oefening 4.23 Compilen lukt niet. De compiler weet niet welk type objectuit de collectie moet worden opgehaald.

pub l i c void c l o s e ( ){

I t e r a t o r i t = l o t s . i t e r a t o r ( ) ;whi l e ( i t . hasNext ( ) ){

Lot l o t = ( Lot ) i t . next ( ) ;i f ( l o t . getHighestBid ( ) != nu l l ){

System . out . p r i n t l n ( l o t . t oS t r i ng ( ) ) ;} e l s e

Page 35: Oplossingen Methodiek van de Informatica

HOOFDSTUK 4. OBJECTEN GROEPEREN 28

{System . out . p r i n t l n ( ”No bid ” ) ;

}}

}

/∗∗∗ Searches f o r unsold t imes and re tu rn s them in∗ an a r r a y l i s t∗∗ @return unsoldLots a r r a y l i s t conta in ing unsold l o t s∗/

pub l i c ArrayList getUnsold ( ){

// array o f unsold itemsArrayList unso ldLots = new ArrayList ( ) ;

I t e r a t o r i t = l o t s . i t e r a t o r ( ) ;whi l e ( i t . hasNext ( ) ){

Lot l o t = ( Lot ) i t . next ( ) ;i f ( l o t . getHighestBid ( ) == nu l l ){

unsoldLots . add ( l o t ) ;}

}

re turn unsoldLots ;}

Oefening 4.26 Aangezien de lotnummers niet veranderen bij het verwijderenvan een lot, worden dit lotnummers die niet meer gebruikt kunnen worden. Hetlotnummer is dan ook geen indicatie meer van hoeveel loten er beschikbaar zijn.De methode getLot zal ook niet meer naar behoren werken.

Oefening 4.37 12h en 22h zijn de drukste momenten van de dag; ze hebbenbeiden een waarde van 8.

Oefening 4.38 Person[] people;

Oefening 4.39 boolean[] vacant;

hourCounts = new in t [ 2 4 ] ;

hourCounts [ hour ]++;

Page 36: Oplossingen Methodiek van de Informatica

HOOFDSTUK 4. OBJECTEN GROEPEREN 29

System . out . p r i n t l n ( ”Hr : Count” ) ;

f o r ( i n t hour = 0 ; hour < hourCounts . l ength ; hour++){

System . out . p r i n t l n ( hour + ” : ” + hourCounts [ hour ] ) ;}

i n t [ ] counts ;

boolean [ ] occupied ; //de g roo t t e wordt pas meegegeven b i jde c r e a t i e

van de array .

Oefening 4.42

• readings = new double[60];

• urls = new String[90];

• machines = new TicketMachine[5];

Oefening 4.43 20 String objecten

Oefening 4.44 Je kan geen methode oproep doen op een veld dat nog nietbestaat. Eerst dus het veld maken en dan de methode oproep doen - bij voorkeurin een methode. Ook was de syntax in de creatie van de array niet juist (’[]’ ipv’()’).

//Veldendouble [ ] p r i c e s = new double [ 5 0 ] ;

//Methodeaanroepp r i c e s . statement ( ) ;

Oefening 4.45 IndexOutOfBoundsException Aangezien de index van een ar-ray altijd begint op 0 gaat tot de lengte-1, zal de waarde van de index nooitgelijk kunnen zijn aan de lengte van de array.

/∗∗∗ Print the hour ly counts .∗ These should have been s e t with a p r i o r∗ c a l l to analyzeHourlyData .∗ While loop in s t ead o f f o r loop .∗/

pub l i c void printHourlyCounts ( )

Page 37: Oplossingen Methodiek van de Informatica

HOOFDSTUK 4. OBJECTEN GROEPEREN 30

{System . out . p r i n t l n ( ”Hr : Count” ) ;i n t hour = 0 ;whi l e ( hour < hourCounts . l ength ){

System . out . p r i n t l n ( hour + ” : ” + hourCounts [ hour] ) ;

hour++;}

}

/∗∗∗ Druk a l l e waarden in de array marks a f d i e∗ g ro t e r z i j n dan het gemiddelde .∗ @param marks Een array van c i j f e rwaa rden .∗ @param mean Het gemiddelde c i j f e r .∗/

pub l i c void p r in t e rGrea t e r ( double [ ] marks , double mean){

f o r ( index = 0 ; index < marks . l ength ; index++){

i f (marks [ index ] > mean){

System . out . p r i n t l n (marks [ index ] ) ;}

}}

pub l i c void l i s tNo t e s ( ){

f o r ( index = 0 ; index < notes . s i z e ; index++){

System . out . p r i n t l n ( notes . get ( index ) ) ;}

}

/∗∗∗ Return the number o f a c c e s s e s that are s to r ed∗ in the l o g f i l e∗ @return t o t a l Total number o f a c c e s s e s∗/

pub l i c i n t numberOfAccesses ( ){

Page 38: Oplossingen Methodiek van de Informatica

HOOFDSTUK 4. OBJECTEN GROEPEREN 31

i n t t o t a l = 0 ;f o r ( i n t index = 0 ; index < hourCounts . l ength ; index

++){

t o t a l += hourCounts [ index ] ;}re turn t o t a l ;

}

/∗∗∗ Gives the bu s i e s t hour∗ Only r e tu rn s one hour as the bu s i e s t hour∗ Method only r e tu rn s the f i r s t bu s i e s t hour∗∗ @return bus iestHour The bu s i e s t hour o f a day∗/

pub l i c i n t bus iestHour ( ){

i n t max = 0 ;i n t bus iestHour = 0 ;

f o r ( i n t index = 0 ; index < hourCounts . l ength ; index++)

{i f (max < hourCounts [ index ] ){

max = hourCounts [ index ] ;bus iestHour = index ;

}}re turn bus iestHour ;

}

/∗∗∗ Gives the qu i e t e s t hour∗ Only r e tu rn s one hour as the qu i e t e s t hour∗ Method only r e tu rn s the f i r s t q u i e t e s t hour∗∗ @return quietes tHour The qu i e t e s t hour o f a day∗/

pub l i c i n t qu ie tes tHour ( ){

i n t min = 0 ;i n t qu ie tes tHour = 0 ;

Page 39: Oplossingen Methodiek van de Informatica

HOOFDSTUK 4. OBJECTEN GROEPEREN 32

f o r ( i n t index = 0 ; index < hourCounts . l ength ; index++)

{i f (min > hourCounts . l ength && hourCounts [ index ]

!= 0){

min = hourCounts [ index ] ;qu ie tes tHour = index ;

}}re turn quietes tHour ;

}

Oefening 4.53 Enkel het eerste uur; dit komt door het statement

max < hourCounts [ index ]

In het geval dat er

max <=hourCounts [ index ]

stond, was het laatste grootste element weergegeven.

/∗∗∗ Returns the bu s i e s t per iod o f two hours∗∗ @return busiestTwoHours The f i r s t hour o f∗ the bu s i e s t per iod o f two hours .∗/

pub l i c i n t busiestTwoHours ( ){

i n t maxTwoHours = 0 ;i n t busiestTwoHours = 0 ;

// length−1 because otherwi se we exceed the arrayl ength

f o r ( i n t index = 0 ; index < hourCounts . length −1; index++)

{i f (maxTwoHours < ( hourCounts [ index ] + hourCounts [

index +1]) ){

maxTwoHours = ( hourCounts [ index ] + hourCounts[ index +1]) ;

busiestTwoHours = index ;}

}re turn busiestTwoHours ;

}

Page 40: Oplossingen Methodiek van de Informatica

HOOFDSTUK 4. OBJECTEN GROEPEREN 33

Oefening 4.55 Zie ook weblog-analyzer2 Accessors voor LogEntry:

/∗∗∗ @return The year f i e l d from the log l i n e .∗/

pub l i c i n t getYear ( ){

re turn dataValues [YEAR] ;}

/∗∗∗ @return The month f i e l d from the log l i n e .∗/

pub l i c i n t getMonth ( ){

re turn dataValues [MONTH] ;}

/∗∗∗ @return The day f i e l d from the log l i n e .∗/

pub l i c i n t getDay ( ){

re turn dataValues [DAY] ;}

In de klasse LogAnalyzer kunnen we nu methodes gelijkaardig aan die vande array hourCounts opstellen. Aangezien dit veel code is die vrij identiek is, ishet beter op algemene accessor en mutator methodes hier voor uit te denken.Een (niet zo goed) voorbeeld van een accessor methode voor informatie m.b.t.tot de dagen weer te geven zou dan zijn:

/∗∗∗ Print the da i l y counts .∗ These should have been s e t with a p r i o r∗ c a l l to analyzeDai lyData .∗/

pub l i c void pr intDai lyCounts ( ){

System . out . p r i n t l n ( ”Hr : Day” ) ;f o r ( i n t day = 0 ; day < dayCounts . l ength ; day++) {

System . out . p r i n t l n ( day + ” : ” + dayCounts [ day ] ) ;}

}

Oefening 4.58

• pro: Als het aantal studenten per klas aan het begin van het jaar vastligtkunnen we beter dit gebruiken; dit zal misbruik van de arrays verhinderenaangezien de lengte toch vastligt.

Page 41: Oplossingen Methodiek van de Informatica

HOOFDSTUK 4. OBJECTEN GROEPEREN 34

• contra: In het geval dat we toch een nieuwe student willen toevoegen, zaldit niet meer gaan. We kunnen een compromis vinden door bijvoorbeeldde lengte van de array in te stellen op het aantal studenten + een spel-ing, bijvoorbeeld 5. Zo kunnen er door het jaar nog maximaal 5 extrastudenten worden toegevoegd aan een array.

/∗∗∗ Pr int s the numbers from 1 to 10 ,∗ us ing a do−whi le loop∗/

pub l i c void printDoWhile ( ){

i n t number = 1 ;

do{

System . out . p r i n t l n (number ) ;number++;}whi le (number <= 10) ;

}

Het verschil met een gewone while lus is dat een do−while lus altijd minstensnmaal het statement uitvoert dat er gevraagd wordt, ongeacht of de test faaltof niet.

/∗∗∗ L i s t a l l notes in the notebook .∗/

pub l i c void l i s tNotesDoWhi le ( ){

i n t index = 0 ;do{

System . out . p r i n t l n ( notes . get ( index ) ) ;index++;// s i z e −1 s i n c e a do whi l e statements i s be ing

used here}whi le ( index < notes . s i z e ( )−1) ;

}

Oefening 4.61 Een switch−case-statement wordt gebruikt in het geval dat jeverschillende cases hebt die je wilt afgaan. In feite is het een overzichtelijker al-ternatief op in mekaar geneste if -statements. Aangezien het wel kan voorkomendat er voor een bepaalde waarde geen case aan verbonden is, is het nodig omeen default in te stellen, d.i. het statement dat wordt uitgevoerd als de input

Page 42: Oplossingen Methodiek van de Informatica

HOOFDSTUK 4. OBJECTEN GROEPEREN 35

aan geen enkele case voldoet. In de les is voor zo ver ik weet het gebruik vanswitch−case-statements afgeraden net door dit gebrek.

Page 43: Oplossingen Methodiek van de Informatica

Hoofdstuk 5

Geavanceerde werking

Oefening 5.2 (Uit de slides van de lessen).Documentatie bevat:

• Naam van de klasse

• Algemene beschrijving

• Lijst van constructoren en methodes

– Parameters– Returnstatements– Idee of bedoeling van de constructor

Oefening 5.3 De methode startsWith gaat na of een String-object al dan nietmet een bepaalde prefix begint en geeft dan een boolean terug; true in het gevaldat het waar is, false in het andere.

Oefening 5.4 De methode endsWith. Heeft als parameter een String-object(een letter bijvoorbeeld) en als return type een boolean true of false .

Oefening 5.5 De eerder geziene methode length. Heeft geen parameters.

Oefening 5.6 Je kan de methodes terugvinden in het overzicht van de meth-odes. Aangezien je gebruik maakt van een webbrowser kan je de daar in inge-bouwde functies zoals een zoekfunctie gebruiken.

//Argument o f header van de methode :pub l i c S t r ing trim ( )

// Voorbeeldaanroep van d i e methode :S t r ing text ; t ex t = ”some text ” ; t ex t . tr im ( ) ;

De methode trim zal witruimtes voor en na de het String-object verwijderen,in het geval dat er geen witruimtes zijn zal er gewoon het oorspronkelijke objectworden teruggegeven als String.

36

Page 44: Oplossingen Methodiek van de Informatica

HOOFDSTUK 5. GEAVANCEERDE WERKING 37

Oefening 5.8 Enkel de regel input = input.trim(); toevoegen.

Oefening 5.9 Voeg regel input = input.toLowerCase(); toe.

Oefening 5.10 Deze methode heeft een boolean als returntype. true als deString-objecten overeen komen, false in het andere geval.

Oefening 5.11 If-statement van de methode start wordt dan:

if(input.equals("bye"))

Dit werkt dan alleen als we enkel ’bye’ of een verwante String (met/zonderhoofdletters, met/zonder witruimtes) zouden ingeven.

Oefening 5.12 Package: java.util.Random. Deze methode wordt gebruiktom (pseudo)-random getallen te genereren. Om een random getal te genererenmoeten we een instantie van de klasse Random maken en een methode van dieinstantie aanroepen om een getal te verkrijgen.

// In laden packageimport java . u t i l .Random ;

// Ve ldde c l a r a t i eRandom randomGenerator ;

randomGenerator = new Random( ) ;

/∗∗∗ Generate a random number .∗ @return Returns a random in t e g e r number .∗/

pub l i c i n t getRandomNumber ( ){

i n t randomNumber ;randomNumber = randomGenerator . next Int ( ) ;r e turn randomNumber ( ) ;

}

Oefening 5.14 Een mogelijke implementatie:

import java . u t i l .Random ;

/∗∗∗ A c l a s s to t e s t the p o s s i b i l i t i e s o f the Random

package .∗ See a l s o Ex . 5 .14

Page 45: Oplossingen Methodiek van de Informatica

HOOFDSTUK 5. GEAVANCEERDE WERKING 38

∗∗ @author Mart i jn Hemeryck∗ @version 2006−02−28∗/

pub l i c c l a s s RandomTester{

// i n i t i a l i s e a Random in s tancep r i va t e Random randomGenerator ;

/∗∗∗ Constructor f o r ob j e c t s o f c l a s s RandomTester∗/

pub l i c RandomTester ( ){

// make a Random ob j e c trandomGenerator = new Random( ) ;

}

/∗∗∗ Pr int s one random number∗/

pub l i c void printOneRandom ( ){

i n t index ;index = randomGenerator . next Int ( ) ;System . out . p r i n t l n ( index ) ;

}

/∗∗∗ Pr int s mu l t ip l e random numbers∗∗ @param howMany the amount o f random numbers to be

pr in ted∗/

pub l i c void printMulitpleRandom ( in t howMany){

i n t amount = 0 ;i n t index ;

whi l e ( amount != howMany){

index = randomGenerator . next Int ( ) ;System . out . p r i n t l n ( index ) ;amount++;

}}

}

Oefening 5.15 Alle random getallen tussen 0 (inclusief) en 100 (exclusief).

Page 46: Oplossingen Methodiek van de Informatica

HOOFDSTUK 5. GEAVANCEERDE WERKING 39

/∗∗∗ Simulates the e f f e c t o f throwing a d i c e∗ Pr int s only va lue s between 1 and 6∗/

pub l i c void throwDice ( ){

i n t index ;index = randomGenerator . next Int (6 ) ;// We add 1 to exc lude 0 and inc lude 6System . out . p r i n t l n ( index+1) ;

}

Oefening 5.17 Een mogelijk, maar niet zo robuuste manier om dit op telossen:

/∗∗∗ Randomly r e tu rn s the p r i n t s ” yes ” , ”no” or ”maybe”∗/

pub l i c void getResponse ( ){

i n t index ;index = randomGenerator . next Int (3 ) ;

i f ( index == 0){

System . out . p r i n t l n ( ” yes ” ) ;}

i f ( index == 1){

System . out . p r i n t l n ( ”no” ) ;}

i f ( index == 2){

System . out . p r i n t l n ( ”maybe” ) ;}

}

/∗∗∗ Print a randomly chosen response , chosen out o f∗ a l i s t o f r e sponse s .∗∗ Compare with code 5 .3∗∗ Flaw : po s s i b l y due to f a c t that ” r e sponse s ” has no

va lue s in i t .∗/

Page 47: Oplossingen Methodiek van de Informatica

HOOFDSTUK 5. GEAVANCEERDE WERKING 40

pub l i c void getResponse ( ){

i n t index ;S t r ing re sponse ;

index = randomGenerator . next Int ( r e sponse s . s i z e ) ;r e sponse = re sponse s . get ( index ) ;

System . out . p r i n t l n ( re sponse ) ;}

Oefening 5.19 Zie ook project tech-support2 of code 5.3 [3].

import java . u t i l . ArrayList ;import java . u t i l .Random ;

/∗∗∗ The responder c l a s s r ep r e s en t s a re sponse generato r

ob j e c t . I t i s∗ used to generate an automatic re sponse .∗ This i s the second ve r s i on o f t h i s c l a s s . This time ,

we generate∗ some random behavior by randomly s e l e c t i n g a phrase

from a prede f ined∗ l i s t o f r e sponse s .∗∗ @author Michael Ko l l ing and David J . Barnes ,

Mart i jn Hemeryck∗ @version 0 .3 ( 2 8 . Feb .2006 )∗/

pub l i c c l a s s Responder {pr i va t e Random randomGenerator ;p r i va t e ArrayList r e sponse s ;

/∗∗∗ Construct a Responder∗/

pub l i c Responder ( ){

randomGenerator = new Random( ) ;r e sponse s = new ArrayList ( ) ;f i l l R e s p o n s e s ( ) ;

}

/∗∗∗ Generate a re sponse .∗∗ @return A s t r i n g that should be d i sp layed as the

re sponse

Page 48: Oplossingen Methodiek van de Informatica

HOOFDSTUK 5. GEAVANCEERDE WERKING 41

∗/pub l i c S t r ing generateResponse ( ){

// Pick a random number f o r the index in thed e f au l t re sponse

// l i s t . The number w i l l be between 0 ( i n c l u s i v e )and the s i z e

// o f the l i s t ( e x c l u s i v e ) .i n t index = randomGenerator . next Int ( r e sponse s .

s i z e ( ) ) ;r e turn ( St r ing ) r e sponse s . get ( index ) ;

}

/∗∗∗ Build up a l i s t o f d e f au l t r e sponse s from which we

can pick one∗ i f we don ’ t know what e l s e to say .∗/

p r i va t e void f i l l R e s p o n s e s ( ){

r e sponse s . add ( ”That sounds odd . Could youde s c r i b e that problem in more d e t a i l ?” ) ;

r e sponse s . add ( ”No other customer has evercomplained about t h i s be f o r e . \n” +

”What i s your systemcon f i gu r a t i on ?” ) ;

r e sponse s . add ( ”That sounds i n t e r e s t i n g . Te l l memore . . . ” ) ;

r e sponse s . add ( ” I need a b i t more in fo rmat ion onthat . ” ) ;

r e sponse s . add ( ”Have you checked that you do nothave a d l l c o n f l i c t ?” ) ;

r e sponse s . add ( ”That i s exp la ined in the manual .Have you read the manual?” ) ;

r e sponse s . add ( ”Your d e s c r i p t i o n i s a b i t wishy−washy . Have you got an expert \n” +

” there with you who couldde s c r i b e t h i s morep r e c i s e l y ?” ) ;

r e sponse s . add ( ”That ’ s not a bug , i t ’ s a f e a tu r e ! ”) ;

r e sponse s . add ( ”Could you e l abo ra t e on that ?” ) ;}

}

Oefening 5.20 De methode zou normaal gezien nog goed moeten werkenwant de methode nextInt krijgt als parameter de grootte van het de ArrayListresponses mee.

i n t index = randomGenerator . next Int ( r e sponse s . s i z e ( ) ) ;

Page 49: Oplossingen Methodiek van de Informatica

HOOFDSTUK 5. GEAVANCEERDE WERKING 42

Oefening 5.21 Een HashMap is een collectie van paren (key, value). Zedienen om zoals bijvoorbeeld in een telefoonboek bepaalde waarden (value) opte zoeken aan de hand van een bepaald gegeven (key).

Oefening 5.22 Een mogelijke implementatie van de klasse MapTester:

Listing 5.1: MapTesterimport java . u t i l . HashMap ;

/∗∗∗ Class to t ry some o f the p o s s i b i l i t i e s o f the HashMap

package∗∗ @author Mart i jn Hemeryck∗ @version 2006−03−28∗/

pub l i c c l a s s MapTester{

pr i va t e HashMap phoneBook ;

/∗∗∗ Create a new MapTester ob j e c t∗/

pub l i c MapTester ( ){

// i n i t i a l i s e a new HashMap ob j e c tphoneBook = new HashMap( ) ;

}

/∗∗∗ Enter a new person in the phonebook .∗∗ @param name name o f person to be added∗ @param number number o f person to be added∗/

pub l i c void enterNumber ( S t r ing name , S t r ingnumber )

{phoneBook . put (name , number ) ;

}

/∗∗∗ Look up the number o f a person in the

phonebook .∗∗ @param name name o f person who ’ s number you

’ re l ook ing f o r∗ @return number number o f the person who ’ s

number you were l ook ing f o r∗/

Page 50: Oplossingen Methodiek van de Informatica

HOOFDSTUK 5. GEAVANCEERDE WERKING 43

pub l i c S t r ing lookUpNumber ( S t r ing name){

St r ing number ;number = ( St r ing ) phoneBook . get (name) ;re turn number ;

}}

Oefening 5.23 Het oude record wordt gewoon overschreven.

Oefening 5.24 Er zullen dan twee records bestaan met dezelfde waarde.

Oefening 5.25 De klasse HashMap bezit al zo een methode: containsKey.Toegepast:

someBoolean = phoneBook . containsKey ( St r ing someKey ) ;

Oefening 5.26 In dat geval wordt er null teruggegeven.

Oefening 5.27 Met behulp van de methode size die de klasse HashMap bezit.

Oefening 5.28 Voorbeeld van de klasse responseMap met gebruik te makenvan de HashMap:

Listing 5.2: Responderimport java . u t i l . HashMap ;

/∗∗∗ The responder c l a s s r ep r e s en t s a re sponse generato r

ob j e c t . I t i s∗ used to generate an automatic re sponse .∗ This i s the second ve r s i on o f t h i s c l a s s . This time ,

we generate∗ some random behavior by randomly s e l e c t i n g a phrase

from a prede f ined∗ l i s t o f r e sponse s .∗∗ @author Michael Ko l l ing and David J . Barnes ,

Mart i jn Hemeryck∗ @version 0 .3 ( 0 3 .Mar . 2006 )∗/

pub l i c c l a s s Responder{

pr i va t e HashMap responseMap ;

/∗∗∗ Construct a Responder∗/

Page 51: Oplossingen Methodiek van de Informatica

HOOFDSTUK 5. GEAVANCEERDE WERKING 44

pub l i c Responder ( ){

responseMap = new HashMap( ) ;f i l lResponseMap ( ) ;

}

/∗∗∗ Generate a re sponse .∗∗ @return A s t r i n g that should be d i sp layed as the

re sponse∗/

pub l i c S t r ing generateResponse ( S t r ing word ){

St r ing response = ( St r ing ) responseMap . get (word ) ;i f ( r e sponse != nu l l ){

re turn response ;} e l s e{

re turn pickDefaultResponse ( ) ;}

}

/∗∗∗ Build up a l i s t o f d e f au l t r e sponse s from which we

can pick one∗ i f we don ’ t know what e l s e to say .∗/

p r i va t e void f i l lResponseMap ( ){

responseMap . put ( ” slow” , ” f a s t ” ) ;responseMap . put ( ”bug” , ” cat ” ) ;responseMap . put ( ” expens ive ” , ” cheap” ) ;

}

pr i va t e St r ing pickDefaultResponse ( ){

re turn ” Defau l t re sponse ” ;}

}

Oefening 5.29

• Overeenkomsten:

– De manier van objecten toevoegen is heel gelijkaardig

– De manier van over alle elementen te itereren is heel gelijkaardig

Page 52: Oplossingen Methodiek van de Informatica

HOOFDSTUK 5. GEAVANCEERDE WERKING 45

• Verschillen

– Voor een lijst staan alle ingevoerde elementen in een welbepaaldevolgorde

– Voor een set maakt de volgorde waarin de elementen worden ingevo-erd niet uit

Oefening 5.30 De methode split moet als parameter meekrijgen waarrondhet String-object wordt opgesplitst. Een voorbeeldje uit de API:

Regex Result: { ”boo”, ”and”, ”foo” }

Oefening 5.31

• Op een spatie of tab:

S t r ing someString = ”some words” ;someString . s p l i t ( ” ” ) ;

• Gescheiden door een dubbele punt:

S t r ing someString = ”some : words” ;someString . s p l i t ( : ) ;

Oefening 5.32 Bij een ArrayList worden de waarden in de volgorde dat ze zijningegeven bewaard en is het mogelijk tweemaal hetzelfde object in te voegen.Een HashSet daarentegen houdt geen vaste volgorde aan en bij het itereren overde set zullen alle waarden in een andere volgorde dan deze ingegeven kunnenteruggegeven worden. Ook kan men geen tweemaal hetzelfde object toevoegenaan een set.

Oefening 5.33 Normaal gezien zou dit geen problemen mogen geven; despatie is nl. op zich ook een String object.

Oefening 5.35 Zie webspace

Oefening 5.36 We kunnen nog wat antwoorden toevoegen aan de methodefillResponseMap van de klasse Responder.

Oefening 5.37 Een manier om dit op te lossen is een array (of een ArrayListte maken in de Responder-klasse die op haar beurt arrays bevat waarin eenreeks van synoniemen of gelijkaardige uitdrukkingen bevatten. Bijvoorbeeld:

Page 53: Oplossingen Methodiek van de Informatica

HOOFDSTUK 5. GEAVANCEERDE WERKING 46

/∗∗∗ Separate array f o r comparing synonyms∗/

p r i va t e void f i l lSynonyms ( ){

St r ing [ ] c rash = new St r ing [ 2 ] ;S t r ing [ ] s low = new St r ing [ 2 ] ;

c rash [ 0 ] = ” crash ” ;crash [ 1 ] = ” c ra she s ” ;

s low [ 0 ] = ” slow” ;s low [ 1 ] = ”performance ” ;

synonyms . add ( crash ) ;synonyms . add ( slow ) ;

}

Dan maken we ook een aparte methode die voor alle input nagaat of hetwoord in een bepaald array kan zitten. Als de opgegeven String in een bepaaldearray zit, laten we deze methode slechts een welbepaalde String teruggeven vooreen groep van synoniemen. Deze String zal dan als key dienen om te vergelijkenin de HashMap.

Oefening 5.40 De documentatie bevat de informatie samengevat op blz. 151in het handboek [3], maar enkel voor de public methodes. private methodesworden niet weergegeven aangezien we ze net private declareren zodat iemandanders ze niet kan (mis)bruiken. Bij het automatisch genereren van de docu-mentatie is het ook belangrijk om de juiste javadoc-symbolen te gebruiken.

Oefening 5.41

• @version: de versie van deze broncode, eventueel met datum

• @author: de naam van diegene(n) die de code geschreven hebben

• @param: de naam en het type van de parameters die meegegeven wordenaan een methode

• @return: de naam en het type van een parameter die wordt teruggegevendoor een bepaalde methode

Oefening 5.42 Een lijst van de overige javadoc tags, te vinden op deze website

• @deprecated: geeft aan dat deze API niet meer gebruikt moet worden

• @throws en @exception: geeft aan, voor een methode, met wat voor invoerde methode zal falen

• @see: voor referenties aan te geven naar andere commentaar

Page 54: Oplossingen Methodiek van de Informatica

HOOFDSTUK 5. GEAVANCEERDE WERKING 47

• @since: geeft aan hoe lang een bepaalde methode al is opgenomen in destandaard-JAVA klassen

• . . .

Oefening 5.44

• drawDemoDeze methode maakt gebruik van de hele reeks van methodes die in deklasse Canvas geımplementeerd staan.

• bounceDeze methode maakt weer gebruikt van een aantal methodes uit de Canvas-klasse en uit de BouncingBall-klasse.

Oefening 5.45

• Voor een Canvas-object aan te maken zijn er drie verschillende methodesnaargelang het aantal parameters dat meegegeven wordt aan de construc-tor. Een String-object moet alleszins altijd worden meegegeven als titelvoor het Canvas-object.

• Voor het Canvas-object zichtbaar te maken: veronderstel volgend object

Canvas canvas ;canvas = new Canvas ( ” v i e rkant ” ) ;

Dan kunnen we het object zichtbaar maken door

canvas . s e tV i s i b l e ( t rue ) ;

• Een lijn tekenen

canvas . drawLine ( i n t x 1 , i n t y 1 , i n t x 2 , i n t y 2 )

waarbij de xi en yi de coordinaten van het eind-en beginpunt van de lijnaangeven

• Iets wissenhier zijn verschillende mogelijkheden voor; voor alles te wissen volstaat

canvas . e r a s e ( ) ;

• Verschil tussen draw en filldraw zorgt er voor dat een bepaalde figuur getekend wordt, fill zorgt dateen bepaalde figuur ingekleurd wordt.

• waitMethode om een vertraging door te geven op bewegende objecten.

Page 55: Oplossingen Methodiek van de Informatica

HOOFDSTUK 5. GEAVANCEERDE WERKING 48

Oefening 5.46 Voorbeeld van wat extra methode-aanroepen

myCanvas . wait (500) ;myCanvas . setForegroundColor ( Color . ye l low ) ;myCanvas . drawString ( ”and many other th ing s ” , 160 , 120) ;

Rectangle r e c t 2 = new Rectangle (40 ,20 ,30 ,20 ) ;

myCanvas . f i l l ( r e c t 2 ) ;

Oefening 5.47 Met behulp van de methode drawLine tekenen we vier lijnenom een rand te tekenen.

/∗∗∗ Tekent een rechthoek op 20 p i x e l s van de rand van het

vens t e r∗/

pub l i c void drawFrame ( ){

i n t p i x e l = 20 ;

myCanvas . drawLine ( p ixe l , p ixe l , width−p ixe l , p i x e l ) ;myCanvas . drawLine ( width−p ixe l , p ixe l , width−p ixe l ,

he ight−p i x e l ) ;myCanvas . drawLine ( width−p ixe l , he ight−p ixe l , p ixe l ,

he ight−p i x e l ) ;myCanvas . drawLine ( p ixe l , p ixe l , p ixe l , he ight−p i x e l ) ;

}

Hierbij wordt verondersteld dat de attributen width en height gebruikt wordenbij het aanmaken van het Canvas-object en niet de actuele parameters 500 en600.

// in a t t r i bu t eni n t width = 600 ;i n t he ight = 500 ;

// in con s t ruc to rpub l i c BallDemo ( ){

myCanvas = new Canvas ( ” Ba l l Demo” , width , he ight );

myCanvas . s e tV i s i b l e ( t rue ) ;}

Oefening 5.48 Normaliter kan je gebruik maken van de methode getSize vooreen Rectangle-object; deze geeft een object van de klasse Dimension die op haarbeurt attributen height en width bezitten. Het probleem hierbij echter is datdeze attributen van het type double zijn en dus niet gebruikt kunnen wordenom bijvoorbeeld een lijn te tekenen met behulp van de methode drawLine die

Page 56: Oplossingen Methodiek van de Informatica

HOOFDSTUK 5. GEAVANCEERDE WERKING 49

allemaal parameters van het type int als input nodig heeft. Misschien dat ditwel mogelijk is via een parse-methode(?)

Oefening 5.49 - 5.53 [2]

• aanpassingen klasse BallDemo

Listing 5.3: BallDemoimport java . awt . ∗ ;import java . awt . geom . ∗ ;import java . u t i l . ArrayList ;import java . u t i l . I t e r a t o r ;import java . u t i l .Random ;import java . u t i l . HashSet ;/∗∗∗ Class BallDemo − prov ide s two shor t demonstrat ions

showing how to use the∗ Canvas c l a s s .∗∗ @author Michael Ko l l ing and David J . Barnes∗ @version 1 .0 (23−Jan−2002)∗/

pub l i c c l a s s BallDemo{

pr i va t e Canvas myCanvas ;

/∗∗∗ Create a BallDemo ob j e c t . Creates a f r e s h

canvas and makes i t v i s i b l e .∗/

pub l i c BallDemo ( ){

myCanvas = new Canvas ( ” Ba l l Demo” , 600 , 500) ;myCanvas . s e tV i s i b l e ( t rue ) ;

}

/∗∗∗ This method demonstrates some o f the drawing

ope ra t i on s that are∗ av a i l a b l e on a Canvas ob j e c t .∗/

pub l i c void drawDemo ( ){

myCanvas . setFont (new Font ( ” h e l v e t i c a ” , Font .BOLD, 14) ) ;

myCanvas . setForegroundColor ( Color . red ) ;

myCanvas . drawString ( ”We can draw text , . . . ” ,20 , 30) ;

Page 57: Oplossingen Methodiek van de Informatica

HOOFDSTUK 5. GEAVANCEERDE WERKING 50

myCanvas . wait (1000) ;

myCanvas . setForegroundColor ( Color . b lack ) ;myCanvas . drawString ( ” . . . draw l i n e s . . . ” , 60 ,

60) ;myCanvas . wait (500) ;myCanvas . setForegroundColor ( Color . gray ) ;myCanvas . drawLine (200 , 20 , 300 , 50) ;myCanvas . wait (500) ;myCanvas . setForegroundColor ( Color . b lue ) ;myCanvas . drawLine (220 , 100 , 370 , 40) ;myCanvas . wait (500) ;myCanvas . setForegroundColor ( Color . b lack ) ;myCanvas . drawLine (290 , 10 , 320 , 120) ;myCanvas . wait (1000) ;

myCanvas . setForegroundColor ( Color . gray ) ;myCanvas . drawString ( ” . . . and shapes ! ” , 110 ,

90) ;

myCanvas . setForegroundColor ( Color . red ) ;

// the shape to draw and movei n t xPos = 10 ;Rectangle r e c t = new Rectangle ( xPos , 150 , 30 ,

20) ;

// move the r e c t ang l e a c r o s s the s c r e enf o r ( i n t i = 0 ; i < 200 ; i ++) {

myCanvas . f i l l ( r e c t ) ;myCanvas . wait (10) ;myCanvas . e r a s e ( r e c t ) ;xPos++;r e c t . s e tLoca t i on ( xPos , 150) ;

}// at the end o f the move , draw once more so

that i t remains v i s i b l emyCanvas . f i l l ( r e c t ) ;

}

/∗∗∗ De gebru ike r kan z e l f k i e z en hoevee l ba l l e n

h i j w i l t l a t en botsen .∗/

pub l i c void bounce ( i n t howmany){

i n t ground = 400 ; // po s i t i o n o f the groundl i n e

myCanvas . e r a s e ( ) ;myCanvas . s e tV i s i b l e ( t rue ) ;

Page 58: Oplossingen Methodiek van de Informatica

HOOFDSTUK 5. GEAVANCEERDE WERKING 51

myCanvas . setForegroundColor ( Color . b lack ) ;myCanvas . drawString ( ”Bouncing Ba l l s v1 . 1 , by

Jeroen Baert ” , 10 , 15) ;myCanvas . drawLine (50 , ground , 550 , ground ) ;myCanvas . setForegroundColor ( Color . green ) ;myCanvas . drawString ( ”Playing ” , 10 , 30) ;// c r e a t e and show the b a l l sArrayList b a l l s = new ArrayList ( ) ;HashSet f i n i s h e d = new HashSet ( ) ;Random randomgenerator = new Random( ) ;f o r ( i n t index = 0 ; index < howmany ; index++){BouncingBall b a l l = new BouncingBall ((50+

randomgenerator . next Int (550) ) ,randomgenerator . next Int (250) , 16 ,

Color . blue , ground , myCanvas ) ;b a l l s . add ( b a l l ) ;b a l l . draw ( ) ;}

// make them bouncewhi l e ( f i n i s h e d . s i z e ( ) != howmany) {

I t e r a t o r i t = b a l l s . i t e r a t o r ( ) ;whi l e ( i t . hasNext ( ) ){

BouncingBall hu id i g eba l = (BouncingBall ) i t . next ( ) ;

myCanvas . wait (30) ;i f ( hu id i g eba l . getXPos i t ion ( ) >= 550){

f i n i s h e d . add (new In t eg e r ( b a l l s .indexOf ( hu id i g eba l ) ) ) ;

hu id i g eba l . e r a s e ( ) ;}e l s e{

hu id i g eba l . move ( ) ;}

}}myCanvas . e r a s eS t r i n g ( ”Playing ” , 10 , 30) ;myCanvas . setForegroundColor ( Color . red ) ;myCanvas . drawString ( ”Stopped” , 10 , 30) ;

}/∗∗∗ Rechthoek rond gebied tekenen .∗ Door Jeroen Baert

Page 59: Oplossingen Methodiek van de Informatica

HOOFDSTUK 5. GEAVANCEERDE WERKING 52

∗ V1.0∗/

pub l i c void drawFrame ( ){

i n t breedte = myCanvas . g e tS i z e ( ) . width −40 ;i n t l eng t e = myCanvas . g e tS i z e ( ) . he ight −40 ;Rectangle r e c t = new Rectangle (20 , 20 ,

breedte , l e ng t e ) ;myCanvas . draw ( r e c t ) ;

}pub l i c void bouncebox ( i n t howmany){

i n t beneden = 400 ; // po s i t i o n o f theground l i n e

i n t boven = 100 ;i n t l i n k s = 100 ;i n t r e ch t s = 400 ;myCanvas . e r a s e ( ) ;myCanvas . s e tV i s i b l e ( t rue ) ;myCanvas . setForegroundColor ( Color . b lack ) ;myCanvas . drawString ( ”Bounce Box Alpha , by

Jeroen Baert ” , 10 , 15) ;myCanvas . setForegroundColor ( Color . green ) ;myCanvas . drawString ( ”Playing ” , 10 , 30) ;myCanvas . drawLine (100 , 100 , 100 , 400) ;myCanvas . drawLine (100 , 400 , 400 , 400) ;myCanvas . drawLine (400 , 400 , 400 , 100) ;myCanvas . drawLine (400 , 100 , 100 , 100) ;// c r e a t e and show the b a l l sArrayList b a l l s = new ArrayList ( ) ;HashSet f i n i s h e d = new HashSet ( ) ;Random randomgenerator = new Random( ) ;f o r ( i n t index = 0 ; index < howmany ; index++){BoxBall b a l l = new BoxBall ( ( l i n k s+

randomgenerator . next Int ( rechts−l i n k s ) ) , (boven+randomgenerator . next Int ( ( beneden−boven ) /2) ) , 10 ,

Color . blue , boven , beneden , l i nk s , rechts ,myCanvas , randomgenerator . next Int (20)−10,

randomgenerator . next Int (20)−10) ;b a l l s . add ( b a l l ) ;b a l l . draw ( ) ;}

// make them bouncewhi l e ( f i n i s h e d . s i z e ( ) != howmany) {

I t e r a t o r i t = b a l l s . i t e r a t o r ( ) ;whi l e ( i t . hasNext ( ) ){

BoxBall hu id i g eba l = ( BoxBall ) i t .

Page 60: Oplossingen Methodiek van de Informatica

HOOFDSTUK 5. GEAVANCEERDE WERKING 53

next ( ) ;myCanvas . wait (10) ;hu id i g eba l . move ( ) ;

}}myCanvas . e r a s eS t r i n g ( ”Playing ” , 10 , 30) ;myCanvas . setForegroundColor ( Color . red ) ;myCanvas . drawString ( ”Stopped” , 10 , 30) ;

}}

• nieuwe klasse BoxBall

Listing 5.4: BoxBallimport java . awt . ∗ ;import java . awt . geom . ∗ ;

/∗∗∗ Class BouncingBall − a g raph i c a l b a l l that

obse rves the e f f e c t o f g rav i ty . The b a l l∗ has the a b i l i t y to move . De t a i l s o f movement are

determined by the b a l l i t s e l f . I t∗ w i l l f a l l downwards , a c c e l e r a t i n g with time due to

the e f f e c t o f grav i ty , and bounce∗ upward again when h i t t i n g the ground .∗∗ This movement can be i n i t i a t e d by repeated c a l l s

to the ”move” method .∗∗ @author Bruce Quig∗ @author Michael Ko l l ing (mik )∗ @author David J . Barnes∗∗ @version 1 .1 (23−Jan−2002)∗/

pub l i c c l a s s BoxBall{

pr i va t e s t a t i c f i n a l i n t GRAVITY = 1 ; // e f f e c to f g rav i ty

p r i va t e i n t ba l lDegradat ion = 1 ;p r i va t e El l ipse2D . Double c i r c l e ;p r i va t e Color c o l o r ;p r i va t e i n t diameter ;p r i va t e i n t xPos i t i on ;p r i va t e i n t yPos i t i on ;p r i va t e f i n a l i n t topPos i t i on ; // y p o s i t i e

van bovenkant

Page 61: Oplossingen Methodiek van de Informatica

HOOFDSTUK 5. GEAVANCEERDE WERKING 54

p r i va t e f i n a l i n t bottomPosit ion ; // yp o s i t i i e van onderkant

p r i va t e f i n a l i n t l e f t P o s i t i o n ; // xpo s i t i o n l i n k s

p r i va t e f i n a l i n t r i g h tPo s i t i o n ; // xpo s i t i o n r e ch t s

p r i va t e Canvas canvas ;p r i va t e i n t ySpeed ; // i n i t i a l

downward speedp r i va t e i n t xSpeed ; // i n i t i a l

onward speed

/∗∗∗ Constructor f o r ob j e c t s o f c l a s s BouncingBall∗∗ @param xPos the ho r i z on t a l coo rd inate o f the

b a l l∗ @param yPos the v e r t i c a l coo rd inate o f the

b a l l∗ @param bal lDiameter the diameter ( in p i x e l s )

o f the b a l l∗ @param ba l lCo l o r the c o l o r o f the b a l l∗ @param groundPos the po s i t i o n o f the ground (

where the wa l l w i l l bounce )∗ @param drawingCanvas the canvas to draw th i s

b a l l on∗/

pub l i c BoxBall ( i n t xPos , i n t yPos , i n tbal lDiameter , Color ba l lCo lo r ,

i n t topPos , i n t bottomPos ,i n t l e f tPos , i n t r ightPos, Canvas drawingCanvas ,i n t ySpeed , i n t xSpeed )

{xPos i t i on = xPos ;yPos i t i on = yPos ;c o l o r = ba l lCo l o r ;diameter = bal lDiameter ;t opPos i t i on = topPos ;bottomPosit ion = bottomPos ;l e f t P o s i t i o n = l e f tPo s ;r i g h tPo s i t i o n = r ightPos ;canvas = drawingCanvas ;t h i s . ySpeed = ySpeed ;t h i s . xSpeed = xSpeed ;

}

/∗∗∗ Draw th i s b a l l at i t s cur rent p o s i t i o n onto

the canvas .

Page 62: Oplossingen Methodiek van de Informatica

HOOFDSTUK 5. GEAVANCEERDE WERKING 55

∗∗/pub l i c void draw ( ){

canvas . setForegroundColor ( c o l o r ) ;canvas . f i l l C i r c l e ( xPos i t ion , yPos i t ion ,

diameter ) ;}

/∗∗∗ Erase t h i s b a l l at i t s cur rent po s i t i o n .∗∗/

pub l i c void e ra s e ( ){

canvas . e r a s eC i r c l e ( xPos i t ion , yPos i t ion ,diameter ) ;

}

/∗∗∗ Move t h i s b a l l accord ing to i t s p o s i t i o n and

speed and redraw .∗∗/

pub l i c void move ( ){

// remove from canvas at the cur rent p o s i t i o ne ra s e ( ) ;// g rav i ty i n c a l c u l e r e nySpeed = ySpeed + GRAVITY;// compute new po s i t i o nyPos i t i on += ySpeed ;xPos i t i on += xSpeed ;

// hit−checki f ( ( ( yPos i t i on >= ( bottomPosit ion − diameter )

) && ( ySpeed != 0) ) ){

yPos i t i on = ( i n t ) ( bottomPosit ion −diameter ) ;

ySpeed = −ySpeed + ba l lDegradat ion ;}i f ( ( ( ( i n t ) xPos i t i on <= ( in t ) l e f t P o s i t i o n ) &&

( xSpeed != 0) ) ){

xPos i t i on = ( i n t ) ( l e f t P o s i t i o n ) ;xSpeed = −xSpeed − ba l lDegradat ion ;

}i f ( ( ( xPos i t i on >= ( r i g h tPo s i t i o n − diameter ) )

&& ( xSpeed != 0) ) ){

xPos i t i on = ( i n t ) ( r i g h tPo s i t i o n −diameter ) ;

Page 63: Oplossingen Methodiek van de Informatica

HOOFDSTUK 5. GEAVANCEERDE WERKING 56

xSpeed = −xSpeed + ba l lDegradat ion ;}i f ( ( ( ( i n t ) yPos i t i on <= ( in t ) topPos i t i on ) && (

ySpeed != 0) ) ){

yPos i t i on = ( i n t ) ( topPos i t i on ) ;ySpeed = −ySpeed − ba l lDegradat ion ;

}

// draw again at new po s i t i o ndraw ( ) ;

}

/∗∗∗ re turn the ho r i z on t a l p o s i t i o n o f t h i s b a l l∗/

pub l i c i n t getXPos i t ion ( ){

re turn xPos i t i on ;}

/∗∗∗ re turn the v e r t i c a l p o s i t i o n o f t h i s b a l l∗/

pub l i c i n t getYPos i t ion ( ){

re turn yPos i t i on ;}

}

Oefening 5.54 Als we waarde van de final -gedeclareerde variabele GRAVITYgroter maken zien we dat de ballen sneller stil komen te liggen.

Listing 5.5: Star Wars name generator

/∗∗∗ Star Wars Name Generator∗∗ Jeroen Baert∗ v1 . 0∗/

pub l i c c l a s s Namegenerator{

/∗∗ Geen cons t ruc to r / ve lden∗/

Page 64: Oplossingen Methodiek van de Informatica

HOOFDSTUK 5. GEAVANCEERDE WERKING 57

pub l i c void generateStarWarsName ( St r ing voornaam ,St r ing achternaam , St r ing moedernaam , St r inggeboo r t ep l aa t s )

{i f ( ( voornaam . l ength ( ) < 2) | | ( achternaam . l ength

( ) < 3) | | (moedernaam . l ength ( ) < 2) | | (g eboo r t ep l aa t s . l ength ( ) < 3) )

{System . out . p r i n t l n ( ”Unable to generate Star

Wars name” ) ;}e l s e{System . out . p r i n t l n ( ”Your Star Wars name i s ” +

achternaam . sub s t r i ng (0 , 3 ) + voornaam . sub s t r i ng(0 , 2 ) + ” ”

+ moedernaam . sub s t r i ng (0 , 2 ) + geboo r t ep l aa t s .s ub s t r i ng (0 , 3 ) ) ;

System . out . p r i n t l n ( ”” ) ;System . out . p r i n t l n ( ”May the f o r c e be with you . . .

” ) ;}

}}

Oefening 5.56 Het probleem met dit codefragment is dat de veranderdewaarde voor s nergens wordt opgeslagen, m.a.w. moet er dit staan

/∗∗∗ Convert a lowercase St r ing to uppercase∗ @param Str ing s∗ @return St r ing S∗/

pub l i c void printUpper ( S t r ing s ){

St r ing S ;S = s . toUpperCase ( ) ;System . out . p r i n t l n (S) ;

}

Oefening 5.57 Zoals de oefening hier staat beschreven zullen de waarden voorde integervariabelen alleen in de methode omgewisseld worden. Om deze voor derest van het programma om te wisselen moet het return-type worden aangepasten moeten de variabelen ook teruggegeven worden (in een array bijvoorbeeld).Uiteindelijk werkt deze methode met lokale variabelen die ophouden te bestaannadat de methode beındigd is.

Page 65: Oplossingen Methodiek van de Informatica

Hoofdstuk 6

Correct werkende objecten

Oefening 6.2 Een voorbeeld van een afdruk

=== Day 28 ===9: Bakker10:11:12:13: Kapper14:15:16:17: Restaurant

Oefening 6.3 Een uur kan niet dubbel besproken worden en wanneer we dittoch proberen zal de boolean false worden teruggegeven worden. De arrayin-spector geeft aan dat de oorspronkelijke waarde niet overschreven wordt.

Oefening 6.4 Het proberen uitvoeren van de methode makeAppointmentvoor ongeldige uren geeft de boolean false terug.

Oefening 6.5 Wanneer de array vol zit worden gewoon alle afspraken afge-drukt bij uitvoeren van de methode showAppointments.

Oefening 6.6 Deze vraag suggereert dat het handig zou zijn een attribuut tehebben dat weergeeft of een dag al volledig vol zit of niet (bijvoorbeeld booleanfullyBooked of iets dergelijks). In het geval dat een dag al volledig besproken

is hoef je dan nl. niet meer alle uren af te gaan om te kijken of er nog tijd isvoor een nieuwe afspraak.

Oefening 6.7 Het is zeker mogelijk om een zelfde Appointment-object opverschillende plaatsen te gebruiken. De tests hebben dan dezelfde geldigheid.Dit is bijvoorbeeld handig voor terugkerende afspraken. Een extra function-aliteit voor terugkerende afspraken om automatisch in te voegen zou daaromook handig zijn (zoals programma’s zoals MS Outlook ook effectief doen).

58

Page 66: Oplossingen Methodiek van de Informatica

HOOFDSTUK 6. CORRECT WERKENDE OBJECTEN 59

Oefening 6.8 Volgende testen slaagden allemaal

• een uur kan niet dubbel besproken worden

• afspraken die aanvangen buiten het bereik van de mogelijke uren wordenniet gemaakt

• het is niet mogelijk een afspraak te maken die al volledig volgeboekt is

• het is mogelijk een Appointment-object meerdere keren binnen een dag tegebruiken

Als we echter bijvoorbeeld een afspraak van 2u maken om 17u, dan wordtdie afspraak gemaakt voor 2u in de klasse Appointment maar slechts voor 1ubijgehouden in de klasse Day. Dit mag natuurlijk niet. We passen hiervoor demethode makeAppointment zodanig dat er ook rekening wordt gehouden metde duur van een afspraak.

/∗∗∗ Make an appointment .∗ @param time The hour at which the appointment s t a r t s .∗ @param appointment The appointment to be made .∗ @return true i f the appointment was s u c c e s s f u l ,∗ f a l s e o therwi se .∗/

pub l i c boolean makeAppointment ( i n t time ,Appointment appointment )

{i n t durat ion = appointment . getDurat ion ( ) ;

i f ( val idTime ( time ) && validTime ( time + durat ion ) ) {i n t startTime = time − START OF DAY;i f ( appointments [ startTime ] == nu l l ) {

// F i l l in a l l the s l o t s f o r the f u l ldurat ion

// o f the appointment .f o r ( i n t i = 0 ; i < durat ion ; i++) {

appointments [ startTime + i ] = appointment;

}re turn true ;

}e l s e {

re turn f a l s e ;}

}e l s e {

re turn f a l s e ;}

}

Oefening 6.9

Page 67: Oplossingen Methodiek van de Informatica

HOOFDSTUK 6. CORRECT WERKENDE OBJECTEN 60

postief negatiefAppointment-objecten aanmaken een uur dubbel bespreken

methode showAppointment oproepen een uur bespreken op een ongeldig uurde volledige dag vullen met afspraken een afspraak proberen te

een Appointment-object meerdere keren gebruiken maken op een volledig besproken dageen afspraak maken van langere duur

Oefening 6.10 Volgende methode doet een negatieve test op het bereik vande appointments-array.

/∗∗∗ Ver i fy that appointments can only take p lace in the

per iod 9−17h∗/

pub l i c void te s tBoundar i e s ( ){

// Star t with a f r e s h Day ob j e c t .day = new Day(1) ;// Create two one−hour appointments .Appointment tooEar ly = new Appointment ( ”Java l e c t u r e ”

, 1) ;Appointment tooLate = new Appointment ( ”Java c l a s s ” ,

1) ;

// Make each appointment at a d i f f e r e n t time .i f ( day . makeAppointment (8 , tooEar ly ) == f a l s e | | day .

makeAppointment (18 , tooLate ) == f a l s e ){

System . out . p r i n t l n ( ” Fa i l ed to make theappointments ” ) ;

} e l s e{

day . showAppointments ( ) ;}

}

Oefening 6.11 De methodes voor de klasse TwoHourTests zijn vrij geli-jkaardig aan die van de vorige oefening (blz.60). Een bepaalde methode isechter wel speciaal en dat is deze om te testen of het mogelijk is om op hetlaatste uur van de dag een afspraak te maken voor twee uren.

/∗∗∗ Ver i fy that , i f a two−hour appointment s t a r t s∗ at the l a s t hour , that i t cannot take p lace∗/

pub l i c void testTwoHourBoundary ( ){

// Star t with a f r e s h Day ob j e c t .day = new Day(1) ;

Page 68: Oplossingen Methodiek van de Informatica

HOOFDSTUK 6. CORRECT WERKENDE OBJECTEN 61

// Create one two−hour appointment at the end o f theday

Appointment justTooLate = new Appointment ( ”Dinner” ,2) ;

// Make the appointment at the end o f the dayi f ( day . makeAppointment (17 , justTooLate ) == f a l s e ){

System . out . p r i n t l n ( ” Fa i l ed to make theappointment” ) ;

System . out . p r i n t l n ( ”Method works proper ly ” ) ;} e l s e{

System . out . p r i n t l n ( ”Appointment made f o r one hour” ) ;

System . out . p r i n t l n ( ”Thus , method doesn ’ t workproper ly ” ) ;

}}

Bij het uitvoeren van deze methode kregen we een IndexOutOfBoundsExceptionwat er op wijst dat de methode makeAppointment dit soort fouten in invoer

op te vangen. Een robuust geschreven methode kan normaliter alle soort inputontvangen (waar het voor geschreven is, uiteraard).

Oefening 6.12 We kunnen ook nog een klasse maken om bijvoorbeeld demethode findSpace uit te testen. Een aantal van de methodes uit de vorigeoefeningen kunnen gemakkelijk hier worden overgenomen zoals bijvoorbeeldmakeThreeAppointments en fillTheDay. (zie ook blz.60).

/∗∗∗ Test i f the f indSpace method works proper ly∗/

pub l i c void testFindSpace ( ){

Appointment needSpace = new Appointment ( ”Gimme somespace ! ” , 1) ;

// make three appointments and t e s t − p o s i t i v et e s t i n g

System . out . p r i n t l n ( ”Make three appointments and t e s t ”) ;

System . out . p r i n t l n ( ”−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−”) ;

makeThreeAppointments ( ) ;i n t value1 = day . f indSpace ( needSpace ) ;System . out . p r i n t l n ( ” F i r s t part r e tu rn s ” + value1 ) ;

System . out . p r i n t l n ( ” ” ) ;

// f i l l the e n t i r e day and t e s t − negat ive t e s t i n g

Page 69: Oplossingen Methodiek van de Informatica

HOOFDSTUK 6. CORRECT WERKENDE OBJECTEN 62

System . out . p r i n t l n ( ” F i l l the e n t i r e day and t e s t ” ) ;System . out . p r i n t l n ( ”−−−−−−−−−−−−−−−−−−−−−−−−−−−−” ) ;f i l lTheDay ( ) ;i n t value2 = day . f indSpace ( needSpace ) ;System . out . p r i n t l n ( ”Second part r e tu rn s ” + value2 ) ;

}

Als output krijgen we hiervoor

Make three appointments and test--------------------------------=== Day 1 ===9: Java lecture10:11:12:13:Java class14:15:16:17: Meet JohnFirst part returns 10

Fill the entire day and test----------------------------=== Day 1 ===9: Test 910: Test 1011: Test 1112: Test 1213: Test 1314: Test 1415: Test 1516: Test 1617: Test 17Second part returns -1

Oefening 6.13 Problemen bij deze aanpak

• veel code wordt opnieuw gebruikt ieder van de testklassen maar tochmoeten we die iedere keer opnieuw overnemen

• ook veel dezelfde soort objecten worden gebruikt

• we moeten telkens zelf nagaan wat de uitkomst is van de test; we moetende testen zelf interpreteren

• voor iedere aanpassing van de methode moeten we test ook aanpassen

Oefening 6.15 Twee methodes, setUp en tearDown. Deze zorgen er respec-tievelijk voor dat een fixture wordt aangemaakt, afgesloten wordt. Gebruikfixtures volgt later.

Page 70: Oplossingen Methodiek van de Informatica

HOOFDSTUK 6. CORRECT WERKENDE OBJECTEN 63

/∗∗∗ Check that the second i s at 10 i f another appointment∗ has a l r eady been scheduled at 9∗/

pub l i c void testFindSpace10 ( ){

Day day1 = new Day(1) ;Appointment appointm1 = new Appointment ( ”Kapper” ,1 ) ;Appointment appointm2 = new Appointment ( ” Barbier ” ,1 ) ;day1 . makeAppointment (9 , appointm1 ) ;a s s e r tEqua l s (10 , day1 . f indSpace ( appointm2 ) ) ;

}

/∗∗∗ Check that f indSpace r e tu rn s −1 i f no space i s∗ av a i l a b l e∗/

pub l i c void te s tF indSpaceFu l l ( ){

Day day = new Day(1) ;// f i l l the e n t i r e day with appointmentsf o r ( i n t i = Day .START OF DAY; i <= Day .

FINAL APPOINTMENT TIME; i++){

day . makeAppointment ( i , new Appointment ( ”Test ” +i , 1) ) ;

}

// try to schedu le one appointment at a random time// during the a l r eady f u l l y scheduled day

Appointment needSpace = new Appointment ( ” I r e a l l yneed an appointment” ,1 ) ;

a s s e r tEqua l s (−1 , day . f indSpace ( needSpace ) ) ;}

/∗∗∗ Check i f f i e l d d e s c r i p t i o n i s i n i t i a l i s e d proper ly∗/

pub l i c void t e s tDe s c r i p t i o n ( ){

Appointment appointment = new Appointment ( ”Dokter” ,2) ;

Page 71: Oplossingen Methodiek van de Informatica

HOOFDSTUK 6. CORRECT WERKENDE OBJECTEN 64

a s s e r tEqua l s ( ”Dokter” , appointment . g e tDe s c r i p t i on ( ) ) ;}

/∗∗∗ Check i f f i e l d durat ion i s i n i t i a l i s e d proper ly∗/

pub l i c void t e s tDura r t i on ( ){

Appointment appointment = new Appointment ( ”Tandarts ” ,3) ;

a s s e r tEqua l s (3 , appointment . getDurat ion ( ) ) ;}

Oefening 6.19 code

/∗∗∗ Check i f a two hour appointment can ove rwr i t e a one

hour∗ appointment∗/

pub l i c void testMakeAppointmentTest ( ){

Day day1 = new Day(1) ;Appointment appointm1 = new Appointment ( ”Something” ,

1) ;Appointment appointm2 = new Appointment ( ” Else ” , 2) ;day1 . makeAppointment (10 , appointm1 ) ;// i t should NOT be po s s i b l e to schedu le a two hour

appointment// at 9 s i n c e i t would ove rwr i t e the f i r s t one at 10a s s e r tEqua l s ( f a l s e , day1 . makeAppointment (9 , appointm2

) ) ;}

Het uitvoeren van deze test lukt echter niet. Dit komt omdat deze versievan Day geen rekening houdt met de eindduur van de afspraak (zoals al eerderopgemerkt blz. 59)

Meer oefeningen van dit genre zijn ook te vinden in de eerste oefenzitting(blz.133).

Oefening 6.21 De eerste maal dat de methode wordt uitgevoerd werkt zezoals ze moet, maar wanneer we de methode nog eens uitvoeren klopt het antwo-ord al niet meer. Daarbij testen we hier maar op een beperkte aantal zaken; zowordt er niet getest of de klasse nog werkt bij invoer van getallen > 10.

Oefening 6.22 Zoals al aangehaald in de vorige oefening (blz.64) geeft demethode testPlus nu een andere waarde terug.

Page 72: Oplossingen Methodiek van de Informatica

HOOFDSTUK 6. CORRECT WERKENDE OBJECTEN 65

Oefening 6.23 Deze methode geeft ook niet altijd hetzelfde resultaat terug.

Oefening 6.24 De methode testMinus heeft hetzelfde probleem als beschrevenstaat voor testPlus; we kunnen de juiste werking er van pas nakijken als we deklasse CalcEngine beter bekijken.

aangeroepen methode displayValue leftOperand previousOperatorbegintoestand 0 0 ’ ’

clear 0 0 ’ ’numberPressed(3) 3 0 ’ ’

plus 0 3 ’+’numberPressed(4) 4 3 ’+’

equals 7 0 ’+’

Oefening 6.25

Oefening 6.26 In de methode equals is geen case voorzien voor het geval dathet attribuut previousOperator gelijk is aan ’ ’.

Oefening 6.27 Toestand na clear: Met andere woorden; het attribuut previousOperator

clear 0 0 ’+’

blijft in dezelfde toestand staan en zal bijgevolg waarschijnlijk de oorzaak zijnvan het probleem.

Oefening 6.28 In de methode clear moet zeker het volgend statement wordentoegevoegd

prev iousOperator =’ ’ ;

Oefening 6.29 9 + 1− 4 = 6; uitvoeren van deze statements geeft ook dit re-sultaat terug. Met dat we enkel de methode clear hebben aangepast en met datde methodes plus en minus zelf de toestand van het attribuut previousOperatoraanpassen, werkt de klasse al voor dit soort gevallen.

Oefening 6.30 We maken gebruik van de methode reportState om in de con-structor en een aantal andere methodes verdere afdrukstatements toe te voegen.

Oefening 6.31 Het probleem stelt zich als we minus en plus na elkaar uitvo-eren. Het attribuut previousOperator blijft namelijk onveranderd na methodeequals.

Oefening 6.32 Persoonlijk vind ik de hoeveelheid uitvoer goed genoeg, miss-chien zelfs iets te veel. In feite geeft het een soort toestandstabel weer zoals ineen voorgaande oefening (blz.65)

Page 73: Oplossingen Methodiek van de Informatica

HOOFDSTUK 6. CORRECT WERKENDE OBJECTEN 66

Oefening 6.33

• handmatig doorlopen van code

– pro

∗ goed inzicht in code, ook goed voor verdereontwikkeling klasse

∗ relatief low-tech

– contra

∗ tijdrovend∗ soms nogal complex, zeker voor grotere klassen

• automatische printstatements

– pro

∗ toestandstabel automatisch ter beschikking

– contra

∗ soms te veel informatie∗ veel werk om statements te plaatsen

en daarna te verwijderen

Listing 6.1: Testklasse calculator project

/∗∗∗ The t e s t c l a s s CalcEngineTest .∗∗ @author Mart i jn Hemeryck∗ @version 0 .1 2006−04−12∗/

pub l i c c l a s s CalcEngineTest extends j un i t . framework .TestCase

{/∗∗∗ Defau l t con s t ruc to r f o r t e s t c l a s s CalcEngineTest∗/

pub l i c CalcEngineTest ( ){}

/∗∗∗ Sets up the t e s t f i x t u r e .∗∗ Cal led be f o r e every t e s t case method .∗/

protec ted void setUp ( ){}

Page 74: Oplossingen Methodiek van de Informatica

HOOFDSTUK 6. CORRECT WERKENDE OBJECTEN 67

/∗∗∗ Tears down the t e s t f i x t u r e .∗∗ Cal led a f t e r every t e s t case method .∗/

protec ted void tearDown ( ){}

/∗∗∗ Test p lus method∗/

pub l i c void t e s tP lu s ( ){

CalcEngine eng ine = new CalcEngine ( ) ;// Make sure the engine i s in a va l i d s t a r t i n g

s t a t e .eng ine . c l e a r ( ) ;// Simulate the p r e s s e s : 3 + 4 = 7engine . numberPressed (3 ) ;eng ine . p lus ( ) ;eng ine . numberPressed (4 ) ;eng ine . equa l s ( ) ;a s s e r tEqua l s (7 , eng ine . getDisp layValue ( ) ) ;

}

/∗∗∗ Test minus method∗/

pub l i c void testMinus ( ){

CalcEngine eng ine = new CalcEngine ( ) ;// Make sure the engine i s in a va l i d s t a r t i n g

s t a t e .eng ine . c l e a r ( ) ;// Simulate the p r e s s e s : 9 − 4 = 5engine . numberPressed (9 ) ;eng ine . minus ( ) ;eng ine . numberPressed (4 ) ;eng ine . equa l s ( ) ;a s s e r tEqua l s (5 , eng ine . getDisp layValue ( ) ) ;

}}

Page 75: Oplossingen Methodiek van de Informatica

HOOFDSTUK 6. CORRECT WERKENDE OBJECTEN 68

Oefening 6.35 [2] De versie voor de calculator waarbij gebruik gemaakt werdvan de bijgeleverde gui

Listing 6.2: Nieuwe versie calculator project/∗∗∗ The main part o f the c a l c u l a t o r doing the c a l c u l a t i o n s

.∗∗ @author Jeroen Baert∗ @version 0 .2 2006−04−12∗/

pub l i c c l a s s CalcEngine{

// Put in s t anc e v a r i a b l e s here .p r i va t e i n t d i sp l ayva lu e ;p r i va t e St r ing l a s t op e r a t o r ;p r i va t e i n t l i n k e r g e t a l ;p r i va t e i n t v laknaoperator ;

/∗∗∗ Create a CalcEngine in s t anc e . I n i t i a l i s e i t s s t a t e

so that i t i s ready∗ f o r use .∗/

pub l i c CalcEngine ( ){

c l e a r ( ) ;}

/∗∗∗ Return the value that should cu r r en t l y be

d i sp layed on the c a l c u l a t o r∗ d i sp l ay .∗/

pub l i c i n t getDisplayValue ( ){

re turn d i sp l ayva lu e ;}

/∗∗∗ A number button was pre s s ed . Do whatever you have

to do to handle i t .∗ The number value o f the button i s g iven as a

parameter .∗/

pub l i c void numberPressed ( i n t number ){

/∗∗∗ Als de l a a t s t e operator bes taat n we z i t t e n

vlak

Page 76: Oplossingen Methodiek van de Informatica

HOOFDSTUK 6. CORRECT WERKENDE OBJECTEN 69

∗ na het indrukken van deze operator dan wordtde hu id ige

∗ disp laywaarde compleet vervangen , nadat ze i sweggeschreven naar de

∗ l i nk e rkan t∗/

i f ( ( l a s t o p e r a t o r !=”none” ) && ( v laknaoperator ==1) )

{/∗∗∗ ( Z e l f s nadat we dus van een ”=” teken

komen , wordt∗ de waarde van het l i n k e r g e t a l n e t j e s

overschreven met het∗ nieuwe g e t a l . )∗/

l i n k e r g e t a l = d i sp l ayva lu e ;d i sp l ayva lu e = number ;v laknaoperator = 0 ;

}e l s e/∗∗∗ In het andere geva l z i j n we een g e t a l aan het

opbouwen∗ o f vu l l en we een nieuw ge t a l in .∗ Dit h e e f t be ide h e t z e l f d e r e s u l t a a t met de

formule h i e ronder .∗/

{d i sp l ayva lu e = 10∗ d i sp l ayva lu e + number ;}

}

/∗∗∗ The ’ p lus ’ button was pre s s ed .∗/

pub l i c void p lus ( ){

/∗∗∗ Als er een vo r i g e operator i s en er i s n i e t op∗ het = teken gedrukt rekent h i j e e r s t u i t∗/

r e k e n e e r s t u i t ( ) ;l i n k e r g e t a l = l i n k e r g e t a l + d i sp l ayva lu e ;l a s t o p e r a t o r = ”+” ;v laknaoperator = 1 ;

}

/∗∗

Page 77: Oplossingen Methodiek van de Informatica

HOOFDSTUK 6. CORRECT WERKENDE OBJECTEN 70

∗ The ’ minus ’ button was pre s s ed .∗/

pub l i c void minus ( ){

/∗∗∗ Als er een vo r i g e operator i s en er i s n i e t op∗ het = teken gedrukt rekent h i j e e r s t u i t∗/

r e k e n e e r s t u i t ( ) ;l i n k e r g e t a l = l i n k e r g e t a l − d i sp l ayva lu e ;l a s t o p e r a t o r = ”−” ;v laknaoperator = 1 ;

}

/∗∗∗ The ’= ’ button was pre s s ed .∗/

pub l i c void equa l s ( ){

/∗∗∗ Nog u i t r ekenen wat er te rekenen va l t∗/

i f ( ( l a s t o p e r a t o r == ”+” ) && ( vlaknaoperator ==0) )

{d i sp l ayva lu e = l i n k e r g e t a l+d i sp l ayva lu e ;l i n k e r g e t a l = d i sp l ayva lu e ;/∗∗∗ Aangeven dat er op het = teken gedrukt i s∗/

l a s t op e r a t o r = ”=” ;}i f ( ( l a s t o p e r a t o r == ”−” ) && ( v laknaoperator ==

0) ){

d i sp l ayva lu e = l i n k e r g e t a l−d i sp l ayva lu e ;l i n k e r g e t a l = d i sp l ayva lu e ;/∗∗∗ Aangeven dat er op het = teken gedrukt i s∗/

l a s t op e r a t o r = ”=” ;}v laknaoperator = 1 ;

}

/∗∗∗ The ’C ’ ( c l e a r ) button was pre s s ed .∗/

pub l i c void c l e a r ( )

Page 78: Oplossingen Methodiek van de Informatica

HOOFDSTUK 6. CORRECT WERKENDE OBJECTEN 71

{d i sp l ayva lu e = 0 ;l a s t o p e r a t o r = ”none” ;l i n k e r g e t a l = 0 ;v laknaoperator = 0 ;

}

/∗∗∗ Voorgaande berekeningen nog u i tvoe r en∗/

pub l i c void r e k e n e e r s t u i t ( ){

i f ( ( l a s t o p e r a t o r == ”+” ) && ( vlaknaoperator !=1) )

{d i sp l ayva lu e = l i n k e r g e t a l + d i sp l ayva lu e ;

}i f ( ( l a s t o p e r a t o r == ”−” ) && ( v laknaoperator !=

1) ){

d i sp l ayva lu e = l i n k e r g e t a l − d i sp l ayva lu e ;}

}/∗∗∗ Return the t i t l e o f t h i s c a l c u l a t i o n engine .∗/

pub l i c S t r ing g e tT i t l e ( ){

re turn ”Rekenmachien” ;}

/∗∗∗ Return the author o f t h i s eng ine . This s t r i n g i s

d i sp layed as i t i s ,∗ so i t should say something l i k e ”Written by H.

Simpson ” .∗/

pub l i c S t r ing getAuthor ( ){

re turn ”by Jeroen Baert ” ;}

/∗∗∗ Return the ve r s i on number o f t h i s eng ine . This

s t r i n g i s d i sp layed as∗ i t i s , so i t should say something l i k e ”Vers ion

1 . 1 ” .∗/

pub l i c S t r ing getVers ion ( )

Page 79: Oplossingen Methodiek van de Informatica

HOOFDSTUK 6. CORRECT WERKENDE OBJECTEN 72

{re turn ”Vers ion 1” ;

}}

Listing 6.3: Testklasse voor nieuwe versie calculator project

/∗∗∗ The t e s t c l a s s eng i n e t e s t .∗∗ @author ( your name)∗ @version ( a ve r s i on number or a date )∗/

pub l i c c l a s s e ng i n e t e s t extends j un i t . framework . TestCase{

/∗∗∗ Defau l t con s t ruc to r f o r t e s t c l a s s eng i n e t e s t∗/

pub l i c eng i n e t e s t ( ){}

/∗∗∗ Sets up the t e s t f i x t u r e .∗∗ Cal led be f o r e every t e s t case method .∗/

protec ted void setUp ( ){}

/∗∗∗ Tears down the t e s t f i x t u r e .∗∗ Cal led a f t e r every t e s t case method .∗/

protec ted void tearDown ( ){}

pub l i c void t e s tP lu s67 ( ){

CalcEngine ca lcEng i1 = new CalcEngine ( ) ;ca l cEng i1 . numberPressed (6 ) ;ca l cEng i1 . numberPressed (0 ) ;ca l cEng i1 . p lus ( ) ;ca l cEng i1 . numberPressed (7 ) ;ca l cEng i1 . equa l s ( ) ;

Page 80: Oplossingen Methodiek van de Informatica

HOOFDSTUK 6. CORRECT WERKENDE OBJECTEN 73

a s s e r tEqua l s (67 , ca l cEng i1 .getDisp layValue ( ) ) ;

}}

Page 81: Oplossingen Methodiek van de Informatica

Hoofdstuk 7

Klassen Ontwerpen

Oefening 7.1 Antwoorden op vragen

• Deze toepassing laadt een venster in waarmee je via tekst met het pro-gramma kan interageren

• Je kan een aantal zgn. kamers bezoeken

• Er zijn 3 ruimtes in het spel

• Als je je op de hoofdingang bevindt zijn de ruimtes als volgt geplaatst:

– oosten: een aula (lecture theatre)

– zuiden: computer lab

– westen: cafetaria (campus pub)

Oefening 7.2 Doel van iedere klasse (summier) samengevat

• GameDeze klasse start het spel op en doet oproepen naar de andere klassen. Infeite regelt deze klasse het verloop van het verdere spel

• CommandKlasse om commando’s in te lezen; commando’s bestaan altijd uit tweewoorden, voorgesteld door twee String objecten.

• CommandWordsKlasse die de standaard commando’s bijhoudt.

• RoomKlasse die de eigenschappen van een kamer moet bijhouden. Dit zijnbijvoorbeeld de uitgangen van een kamer.

• ParserKlasse die alle ingegeven tekst gaat vergelijken met de commando’s gedefinieerdin het programma. Het programma reageert uiteraard alleen maar als deingegeven tekst overeen komen met commando’s in het programma.

74

Page 82: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 75

Figuur 7.1: Wereld die gebruikt wordt in het programma

Oefening 7.3 Als voorbeeld neem ik een kaartje over getekend door eenmedestudent [2] - ik hoop dat hij daar geen probleem van maakt.

Oefening 7.4 Voor de volgende oefeningen staat vanaf hier een opsommingvan de veranderingen. De uiteindelijke code wordt later gegeven.1

Voor deze oefening is de het nieuwe kaartje (7.1) omgezet in JAVA-code.

Oefening 7.5 Methode printLocationInfo toegevoegd

Oefening 7.6 Aanpassingen uit boek doorgevoerd

• accessor in Room

• nextRoom via accessor

• printLocationInfo aangepast

Oefening 7.7 Schrijven van een methode getExitString (zie handboek [3] blz.215).

Oefening 7.8 Aanpassingen uit boek doorvoeren: werken met een HashMap

• methode setExit

• methode getExit

• manier van werken met attributen in klasse Game1Aangezien er constant veranderingen worden doorgevoerd, is het wel zo dat de tussen-

oplossingen hier niet gegeven worden.

Page 83: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 76

Oefening 7.9 De methode keySet geeft een object van de klasse Set terugdie in feite een verzameling is van alle sleutel (of key) waarden. In het gevalvan het voorbeeld houdt ze dus een verzameling bij van String-objecten die derichtingen aangeven.

Oefening 7.10 De methode getExitString maakt allereerst een lokale vari-abele returnString aan die geınitialiseerd wordt met de waarde ”Exits”2. Daarnawordt er een lokale variabele keys van het type Set aangemaakt die alle mogelijkewaarden voor de richtingen van een welbepaalde kamer inleest via de methodekeySet (blz.76). Vervolgens worden die waarden (ook van het type String) danuitgelezen een toegevoegd aan de eerder geınitialiseerde String returnString.Uiteindelijk wordt deze String dan teruggegeven.

Oefening 7.11 Aanpassingen:

• klasse Room

– methode getExitString

– methode getLongDescription

• klasse Game

– methode printLocationInfo

Oefening 7.14 Opdracht look toegevoegd

Oefening 7.15 Opdracht eat toegevoegd

Oefening 7.16 Wijzigingen uit handboek aangebracht

• methode showAll

• methode printHelp

• methode showCommands

Oefening 7.17 Als je nu een nieuwe opdracht toevoegt zal het niet nodig zijnom de commentaar in printHelp aan te passen.

Oefening 7.18 Aanpassingen:

• nieuwe methode getCommandList in klasse Commandwords die Stringarray doorgeeft.

• methode showCommands van de Parser geeft String gewoon door

• afprinten van de String gebeurt in klasse Game.2Ik zal verder proberen zo veel mogelijk Engels te gebruiken in mijn code; in het Neder-

landstalige handboek heeft men de slechte gewoonte om nog veel zaken in het Nederlands tevertalen

Page 84: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 77

Oefening 7.19 Van de site van Wikipedia [1]

Model-View-Controller (of MVC) is een manier om object-georinteerdetoepassingen te structureren bij het programmeren. In plaats vanalle applicatielogica (het model), alle gebruikersinterfacelogica (in-put, m.a.w. controllers, en output, m.a.w. views) samen in nmonolitisch blok te programmeren, worden MVC-applicaties zodaniggeschreven dat alle applicatielogica in model-objecten zit, alle ge-bruikersinputcode in controller-objecten zit en alle gebruikersout-putcode in view-objecten zit. Op deze manier worden verschillendeverantwoordelijkheden (de applicatie, haar input en haar output)ook technisch van elkaar gescheiden wat de leesbaarheid en herbruik-baarheid van de code ten goede komt.

Toegepast op ons programma omvat het dus het volgende:

• model : het idee achter een verplaatsing; wat is een verplaatsing

• view : de gui of de manier hoe de gebruiker het programma te zien krijgt(tekst in ons geval)

• controller : manier waarop het programma reageert op de input van degebruiker. In feite is de controller de brug tussen het view-aspect en hetmodel-aspect. (het idee achter de tekst om te zetten in commando’s).

Oefening 7.20 Schrijf een aparte klasse Item die alle eigenschappen bijhoudtm.b.t. een voorwerp. Deze eigenschappen zijn een beschrijving van het objecten het gewicht van het object.

Oefening 7.21 De informatie over zo een object wordt opgeslagen in respec-tievelijk een String en een int. Deze twee types zouden dan rechtstreeks moetenworden doorgegeven aan de klasse Room die de andere eigenschappen van eenkamer bevat. Deze kan dan later beslissen wat daar mee moet gebeuren (af-drukken of iets anders).

Oefening 7.22 Wijzigingen in de klasse Room

• Methode addItem: om nieuwe items toe te voegen

• Methode getItemString: om de beschrijving van de Item-objecten alsString terug te krijgen

• Methode getItem: geeft een ArrayList terug met alle items voor een wel-bepaalde kamer

• Methode getLongDescription: aangepast om de informatie af te drukken.In de klasse Game gebeurt er met andere woorden niets buiten dan hettoevoegen van de items aan een bepaalde kamer

Page 85: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 78

Oefening 7.23 Commando back toegevoegd: aanpassingen

• attribuut lastRoom aangemaakt dat bijhoudt welke de laatst bezochtekamer is. Deze onthoudt dan wel maar 1 kamer.

• methode goRoom aangepast zodat deze de inhoud van attribuut lastRoomaanpast bij het betreden van een nieuwe kamer.

• methode processCommand en de lijst met beschikbare commando’s aangepastzodat deze het commando back herkent.

• methode back geschreven

Oefening 7.24 Mijn methode back is zodanig geschreven dat het gaat kijkenof er een tweede woord wordt ingegeven. Het tweede woord wordt als parameteraan de methode meegegeven.

Oefening 7.25 Deze methode werkt met een attribuut dat enkel de laatstbezochte kamer onthoudt. Als je de methode twee keer na elkaar uitvoert zalhet gewoon de kamer teruggeven waar je je op dit moment bevindt. Om volledigte werken zou je een array of iets dergelijks moeten gebruiken om alle bezochtekamers bij te houden.

Oefening 7.26 Stack gebruikt om de vorige kamers bij te houden. Een Stackgedraagt zich zoals een Vector (is er zelfs een abstracte klasse van) en kort gezegdis het gewoon een array waar we gemakkelijk objecten aan kunnen toevoegen.Wijzigingen:

• attribuut lastRoom is een Stack van allemaal Room objecten

• methode goRoom verandert de toestand van lastRoom met behulp vaneen methode oproep van klasse Stack

• methode back werkt uiteraard nu ook via methodeaanroepen uit de klasseStack

Oefening 7.27 Basisfunctionaliteitstests:

• testen op hoe de commando’s worden geınterpreteerd en omgezet voor deverdere verwerking van het spel

• testen op hoe Room-objecten worden aangemaakt, wat hun toestand isna iedere aanroep van een bepaalde methode. Bijvoorbeeld: de laatstbesproken oplossing voor terug te keren naar een bepaalde kamer testenonder verschillende omstandigheden (blz 78).

• testen op hoe objecten van Item gebruikt worden in het hele spel

• . . .

Page 86: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 79

Oefening 7.28 Om de functionaliteit van de Parser en de andere klassen dieinstaan voor het interpreteren van de gebruikerinput, zou het inderdaad mogelijkmoeten zijn om een testklasse te schrijven die zelf het invoeren van gebruikersin-put simuleert. Deze zou dan, om snel en makkelijk te kunnen werken, tekst uiteen bepaald bestand moeten kunnen inlezen en doorgeven als String aan hetprogramma (net zoals een menselijke gebruiker dat zou doen). Met dat we detekst laten uitlezen uit een bepaald bestand kunnen we de input waarop getestwordt niet alleen op voorhand goed definieren maar daarna ook nog naar wensaanpassen.

Oefening 7.29 e.v. Een volledige juiste oplossing bestaat er voor dit projectvanaf hier niet meer. Bijgevoegd wel een overzicht van alle klassen die ik hebuitgewerkt tot nu toe. Mogelijk zitten hier wel nog wat fouten in en als ik nogwat tijd heb zal ik deze er nog wel proberen uit te werken.

Listing 7.1: klasse Gameimport java . u t i l . Stack ;

/∗∗∗ This c l a s s i s the main c l a s s o f the ”World o f Zuul”

app l i c a t i o n .∗ ”World o f Zuul” i s a very simple , t ex t based

adventure game . Users∗ can walk around some scenery . That ’ s a l l . I t should

r e a l l y be extended∗ to make i t more i n t e r e s t i n g !∗∗ To play t h i s game , c r e a t e an in s t anc e o f t h i s c l a s s

and c a l l the ” play ”∗ method .∗∗ This main c l a s s c r e a t e s and i n i t i a l i s e s a l l the

o the r s : i t c r e a t e s a l l∗ rooms , c r e a t e s the par s e r and s t a r t s the game . I t

a l s o eva lua t e s and∗ execute s the commands that the par s e r r e tu rn s .∗∗ @author Michael Ko l l ing and David J . Barnes∗ Marti jn Hemeryck∗ @version 1 .4 2006−04−14∗/

pub l i c c l a s s Game{

// par s e r the i n t e r p r e t t ex t inputp r i va t e Parser par s e r ;// p laye r who p lays the gamepr i va t e Player p laye r ;

/∗∗

Page 87: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 80

∗ Create the game and i n i t i a l i s e i t s i n t e r n a l map .∗/

pub l i c Game( ){

// c r e a t e the p laye r f o r t h i s gamep layer = new Player ( ) ;// c r e a t e the rooms f o r t h i s gamecreateRooms ( ) ;// par s e rpar s e r = new Parser ( ) ;

}

/∗∗∗ Create a l l the rooms and l i n k t h e i r e x i t s toge the r

.∗/

p r i va t e void createRooms ( ){

Room cs , grasVeldLinks , moete , grasVeldRechts , m6, m7, f i e t s e n S t e l P l a a t s , pEnO;

Item pro j e c to r , pen ;

// c r e a t e the roomscs = new Room(” in the bu i l d i ng o f

computerwetenschappen” ) ;grasVeldLinks = new Room( ”on the f i e l d between

the bu i l d i ng o f computerwetenschappen and theM bu i l d ing ” ) ;

moete = new Room( ” in the campus c a f e t e r i a ” ) ;grasVeldRechts = new Room(”op the f i e l d between

the M bu i l d ing and the P&O bu i l d ing ” ) ;m6 = new Room(” in the l e c t u r e thea t r e M6” ) ;m7 = new Room(” in the l e c t u r e thea t r e M7” ) ;f i e t s e n S t e l P l a a t s = new Room(”by the b i c y c l e

stands in f r on t o f the M bu i l d ing ” ) ;pEnO = new Room( ” in the l ab s o f P&O” ) ;

// c r e a t e the itemsp r o j e c t o r = new Item ( ” p r o j e c t o r ” , 1500) ;pen = new Item ( ”pen” , 20) ;

// i n i t i a l i s e the room e x i t scs . s e tEx i t ( ” ea s t ” , grasVeldLinks ) ;grasVeldLinks . s e tEx i t ( ” north ” , moete ) ;grasVeldLinks . s e tEx i t ( ” south ” , f i e t s e n S t e l P l a a t s )

;moete . s e tEx i t ( ” ea s t ” , grasVeldRechts ) ;moete . s e tEx i t ( ” south ” , grasVeldLinks ) ;grasVeldRechts . s e tEx i t ( ” ea s t ” , pEnO) ;

Page 88: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 81

grasVeldRechts . s e tEx i t ( ” south” , f i e t s e n S t e l P l a a t s) ;

grasVeldRechts . s e tEx i t ( ”west ” , moete ) ;m6. s e tEx i t ( ” ea s t ” , m7) ;m6. s e tEx i t ( ” south” , f i e t s e n S t e l P l a a t s ) ;m7. s e tEx i t ( ” south” , f i e t s e n S t e l P l a a t s ) ;m7. s e tEx i t ( ”west ” , m6) ;f i e t s e n S t e l P l a a t s . s e tEx i t ( ” north ” , m7) ;f i e t s e n S t e l P l a a t s . s e tEx i t ( ” ea s t ” , grasVeldRechts )

;f i e t s e n S t e l P l a a t s . s e tEx i t ( ”west ” , grasVeldLinks ) ;pEnO. s e tEx i t ( ”west ” , grasVeldRechts ) ;

// c r e a t e some items in a roomm6. addItem ( ” p r o j e c t o r ” , p r o j e c t o r ) ;m7. addItem ( ”pen” , pen ) ;

p laye r . setCurrentRoom ( grasVeldLinks ) ;}

/∗∗∗ Main play rout ine . Loops un t i l end o f play .∗/

pub l i c void play ( ){

printWelcome ( ) ;

// Enter the main command loop . Here werepea t ed ly read commands and

// execute them un t i l the game i s over .

boolean f i n i s h e d = f a l s e ;whi l e ( ! f i n i s h e d ) {

Command command = par s e r . getCommand ( ) ;f i n i s h e d = processCommand (command) ;

}System . out . p r i n t l n ( ”Thank you f o r p lay ing . Good

bye . ” ) ;}

/∗∗∗ Print out the opening message f o r the p laye r .∗/

p r i va t e void printWelcome ( ){

System . out . p r i n t l n ( ) ;System . out . p r i n t l n ( ”Welcome to the World o f Zuul !

” ) ;System . out . p r i n t l n ( ”World o f Zuul i s a new ,

i n c r e d i b l y bor ing adventure game . ” ) ;

Page 89: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 82

System . out . p r i n t l n ( ”Type ’ he lp ’ i f you need help .” ) ;

System . out . p r i n t l n ( ) ;p laye r . p r i n tLoca t i on In f o ( ) ;

}

/∗∗∗ Given a command , p roce s s ( that i s : execute ) the

command .∗ I f t h i s command ends the game , t rue i s returned ,

o therwi se f a l s e i s∗ returned .∗/

p r i va t e boolean processCommand (Command command){

boolean wantToQuit = f a l s e ;

i f (command . isUnknown ( ) ) {System . out . p r i n t l n ( ” I don ’ t know what you

mean . . . ” ) ;r e turn f a l s e ;

}

St r ing commandWord = command . getCommandWord ( ) ;i f (commandWord . equa l s ( ” he lp ” ) )

pr intHe lp ( ) ;e l s e i f (commandWord . equa l s ( ”go” ) )

p laye r . goRoom(command) ;e l s e i f (commandWord . equa l s ( ”back” ) )

p laye r . back (command) ;e l s e i f (commandWord . equa l s ( ”name” ) )

p laye r . setPlayerName (command) ;e l s e i f (commandWord . equa l s ( ” look ” ) )

p laye r . look ( ) ;e l s e i f (commandWord . equa l s ( ” eat ” ) )

p laye r . eat ( ) ;e l s e i f (commandWord . equa l s ( ” get ” ) )

p laye r . pickUpItem (command) ;e l s e i f (commandWord . equa l s ( ”drop” ) )

p laye r . dropItem (command) ;e l s e i f (commandWord . equa l s ( ” items ” ) )

p laye r . l i s t I t em s ( ) ;e l s e i f (commandWord . equa l s ( ” qu i t ” ) )

wantToQuit = p laye r . qu i t (command) ;

re turn wantToQuit ;}

// implementat ions o f user commands :

Page 90: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 83

/∗∗∗ Print out some help in fo rmat ion .∗ Here we pr in t some stupid , c r yp t i c message and a

l i s t o f the∗ command words .∗/

p r i va t e void pr intHe lp ( ){

System . out . p r i n t l n ( ”You are l o s t . You are a lone .You wander” ) ;

System . out . p r i n t l n ( ”around at the un i v e r s i t y . ” ) ;System . out . p r i n t l n ( ) ;System . out . p r i n t l n ( ”Your command words are : ” ) ;S t r ing [ ] validCommands = par s e r . showCommands ( ) ;

f o r ( i n t i = 0 ; i < validCommands . l ength ; i++){

System . out . p r i n t ( validCommands [ i ] + ” ” ) ;}System . out . p r i n t l n ( ) ;

}}

Listing 7.2: klasse Playerimport java . u t i l . Stack ;import java . u t i l . ArrayList ;import java . u t i l . I t e r a t o r ;import java . u t i l . HashMap ;

/∗∗∗ This c l a s s i s part o f the ”World o f Zuul” app l i c a t i o n .∗ ”World o f Zuul” i s a very simple , t ex t based adventure

game .∗∗ Represents a p laye r∗∗ @author Mart i jn Hemeryck∗ @version 0 .1 2006−04−14∗/

pub l i c c l a s s Player{

// the name o f the p laye rp r i va t e St r ing playerName ;// the maximum amount o f weight a p laye r can take

with him/herp r i va t e i n t maxCarryWeight ;// the room the p laye r i s cu r r en t l y inp r i va t e Room currentRoom ;// the rooms a p laye r has v i s i t e dp r i va t e Stack lastRoom ;

Page 91: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 84

// the items the p laye r has taken with himpr i va t e ArrayList i t emLi s t ;

/∗∗∗ Constructor f o r ob j e c t s o f c l a s s Player∗/

pub l i c Player ( ){

// the name o f the p laye rplayerName = ”defaultName” ;// d e f au l t maximum car ry ing weight : 10 kgmaxCarryWeight = 10000;// i n i t i l i a s e lastRoomlastRoom = new Stack ( ) ;// i n i t i l i a s e the i t e m l i s ti t emLi s t = new ArrayList ( ) ;

}

/∗∗∗ Change the name o f the p laye r∗ @param Str ing playerName The new name o f the

p laye r∗/

p r i va t e void setPlayerName ( St r ing playerName ){

t h i s . playerName = playerName ;System . out . p r i n t l n ( ”Your name i s ” + playerName ) ;

}

/∗∗∗ Change the name o f the player , t h i s time v ia

command∗ @param Command playerName The name o f the p laye r∗/

pub l i c void setPlayerName (Command commandName){

i f ( ! commandName . hasSecondWord ( ) ){

System . out . p r i n t l n ( ”What i s your name again ?”) ;

S t r ing playerName = ” Defau l t name” ;re turn ;

}e l s e{

setPlayerName ( ( S t r ing ) commandName .getSecondWord ( ) ) ;

}}

Page 92: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 85

/∗∗∗ Change the maximum weight∗ @param in t maxCarryWeight The new weight the

p laye r can carry at maximum∗/

pub l i c void setMaxCarryWeight ( i n t maxCarryWeight ){

t h i s . maxCarryWeight = maxCarryWeight ;}

/∗∗∗ Get the name o f the p laye r∗ @return St r ing playerName The name o f the p laye r∗/

pub l i c S t r ing getPlayerName ( ){

re turn playerName ;}

/∗∗∗ Get the weight a p laye r can carry at maximum∗ @return maxCarryWeight The weight a p laye r can

carry at maximum∗/

pub l i c i n t getMaxCarryWeight ( ){

re turn maxCarryWeight ;}

/∗∗∗ Get the room the p laye r i s cu r r en t l y in∗ @return Room currentRoom The room the p laye r i s

cu r r en t l y in∗/

pub l i c Room getCurrentRoom ( ){

re turn currentRoom ;}

/∗∗∗ Get a stack o f the rooms a l l p laye r has a l r eady

v i s i t e d∗ @return Stack lastRoom A stack o f the rooms the

p laye r has a l r eady v i s i t e d∗/

pub l i c Stack getLastRoom ( ){

re turn lastRoom ;}

Page 93: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 86

/∗∗∗ Sets the cur rent room∗ @Room currentRoom The room the p laye r i s cu r r en t l y

in∗/

pub l i c void setCurrentRoom (Room currentRoom ){

t h i s . currentRoom = currentRoom ;}

/∗∗∗ Returns a l i s t o f the items a l ready taken with the

p laye r∗ @return ArrayList i t emLi s t A l i s t o f the items the

p laye r has with him/her∗/

pub l i c ArrayList ge t I t emLi s t ( ){

re turn i t emLi s t ;}

/∗∗∗ Add new items to the l i s t o f i tems∗ @param Item item The item to be added to the

i t e m l i s t∗/

p r i va t e void pickUpItem ( Item item ){

i t emLi s t . add ( item ) ;

}

/∗∗∗ Drop items and get them o f f the l i s t i tems∗ f o r now , items only occur once in the l i s t !∗ @param Item dropItem The item to get o f the l i s t∗/

p r i va t e void dropItem ( Item item ){

// f i nd where the item i s in the l i s t// f o r now , they only occur once in the l i s ti n t whichItem = itemLi s t . indexOf ( item ) ;// remove the item at the l o c a t i o n s p e c i f i e d

be f o r ei t emLi s t . remove ( whichItem ) ;

}

/∗∗∗ I n t e r p r e t the commands as items and take the item

you wish to take

Page 94: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 87

∗ @param Command command The d e s c r i p t i o n o f the itemyou wish take with you

∗/pub l i c void pickUpItem (Command command){

i f ( ! command . hasSecondWord ( ) ){

System . out . p r i n t l n ( ”Pick up what?” ) ;r e turn ;

}

// The d e s c r i p t i o n o f the itemSt r ing i t emDesc r ip t i on = command . getSecondWord ( ) ;

// The item correspond ing to the d e s c r i p t i o nItem itemInRoom = currentRoom . getItem (

i t emDesc r ip t i on ) ;

// Add the item to the l i s t o f i tems a l readypicked up

pickUpItem ( itemInRoom) ;

// S ince you ’ ve picked up the item , i t should nolonge r be in the room

currentRoom . removeItem ( i t emDesc r ip t i on ) ;}

/∗∗∗ I n t e r p r e t the commands as items and drop the items

you wish to drop∗ @param Command command The d e s c r i p t i o n o f the item

you wish to drop∗/

pub l i c void dropItem (Command command){

i f ( ! command . hasSecondWord ( ) ){

System . out . p r i n t l n ( ”Drop what?” ) ;r e turn ;

}

// The d e s c r i p t i o n o f the itemSt r ing i t emDesc r ip t i on = command . getSecondWord ( ) ;

// The item correspond ing to the d e s c r i p t i o nItem itemInRoom = currentRoom . getItem (

i t emDesc r ip t i on ) ;

// Remove the item from the l i s t o f i tems takenwith you

Page 95: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 88

dropItem ( itemInRoom) ;

// S ince you ’ ve dropped the item i t should be inthe room

currentRoom . addItem ( i temDescr ipt ion , itemInRoom) ;}

/∗∗∗ Try to go to one d i r e c t i o n . I f the re i s an ex i t ,

ente r∗ the new room , otherwi se p r i n t an e r r o r message .∗/

pub l i c void goRoom(Command command){

i f ( ! command . hasSecondWord ( ) ) {// i f the re i s no second word , we don ’ t know

where to go . . .System . out . p r i n t l n ( ”Go where?” ) ;r e turn ;

}

St r ing d i r e c t i o n = command . getSecondWord ( ) ;

//Try to l eave cur rent room .Room nextRoom = currentRoom . getEx i t ( d i r e c t i o n ) ;

i f ( nextRoom == nu l l )System . out . p r i n t l n ( ”There i s no door ! ” ) ;

e l s e{

lastRoom . push ( currentRoom ) ;currentRoom = nextRoom ;p r i n tLoca t i on In f o ( ) ;

}}

/∗∗∗ Go back to the room l a s t v i s i t e d∗/

pub l i c void back (Command command){

i f (command . hasSecondWord ( ) ){

System . out . p r i n t l n ( ”What do you mean?” ) ;r e turn ;

}

i f ( ! lastRoom . empty ( ) ){

currentRoom = (Room) lastRoom . pop ( ) ;

Page 96: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 89

System . out . p r i n t l n ( ”You j u s t went back oneroom” ) ;

p r i n tLoca t i on In f o ( ) ;}

e l s e{

System . out . p r i n t l n ( ”You are at the s t a r t i n gpo int ” ) ;

p r i n tLoca t i on In f o ( ) ;}

}

/∗∗∗ Pr int s the in fo rmat ion regard ing po s i t i o n again∗/

pub l i c void look ( ){

System . out . p r i n t l n ( currentRoom . getLongDescr ipt ion( ) ) ;

}

/∗∗∗ Method to add command eat∗/

pub l i c void eat ( ){

System . out . p r i n t l n ( ”You ’ ve f i n i s h e d ea t ing andare no longe r hungry” ) ;

}

/∗∗∗ ”Quit” was entered . Check the r e s t o f the command

to see∗ whether we r e a l l y qu i t the game . Return true , i f

t h i s command∗ qu i t s the game , f a l s e o therwi se .∗/

pub l i c boolean qu i t (Command command){

i f (command . hasSecondWord ( ) ) {System . out . p r i n t l n ( ”Quit what?” ) ;r e turn f a l s e ;

}e l s e

re turn true ; // s i g n a l that we want to qu i t}

/∗∗∗ L i s t the items the p laye r has with him

Page 97: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 90

∗/pub l i c void l i s t I t em s ( ){

St r ing r e tu rnS t r i ng = ” items you are cu r r en t l yca r ry ing : ” ;

f o r ( I t e r a t o r i t e r = i t emLi s t . i t e r a t o r ( ) ; i t e r .hasNext ( ) ; )

{Item arrayItem = ( Item ) i t e r . next ( ) ;r e tu rnS t r i ng += ” ” + ( St r ing ) arrayItem .

ge t I t emDesc r ip t i on ( ) ;}System . out . p r i n t ( r e tu rnS t r i ng ) ;

}

/∗∗∗ Print the in fo rmat ion o f the cur rent l o c a t i o n∗/

pub l i c void p r i n tLoca t i on In f o ( ){

System . out . p r i n t l n ( currentRoom . getLongDescr ipt ion( ) ) ;

}}

Listing 7.3: klasse Itemimport java . u t i l . HashMap ;

/∗∗∗ This c l a s s i s part o f the ”World o f Zuul” app l i c a t i o n .∗ ”World o f Zuul” i s a very simple , t ex t based adventure

game .∗∗ Contains the p r op e r t i e s o f an item∗∗ @author Mart i jn Hemeryck∗ @version 0 .2 2006−04−14∗/

pub l i c c l a s s Item{

// a d e s c r i p t i o n o f the itempr i va t e St r ing i t emDesc r ip t i on ;// the weight o f the item , in gp r i va t e i n t itemWeight ;

/∗∗∗ Constructor f o r ob j e c t s o f c l a s s Item∗/

Page 98: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 91

pub l i c Item ( St r ing i temDescr ipt ion , i n titemWeight )

{// i n i t i a l i s e s the d e s c r i p t i o n f o r the itemth i s . i t emDesc r ip t i on = i temDesc r ip t i on ;// i n i t i a l i s e s the weight f o r the itemth i s . itemWeight = itemWeight ;

}

/∗∗∗ Returns the d e s c r i p t i o n o f the item∗ @return St r ing i t emDesc r ip t i on The d e s c r i p t i o n

o f the item∗/

pub l i c S t r ing ge t I t emDesc r ip t i on ( ){

re turn i t emDesc r ip t i on ;}

/∗∗∗ Returns the weight o f the item in g∗ @return i n t itemWeight∗/

pub l i c i n t getItemWeight ( ){

re turn itemWeight ;}

}

Listing 7.4: klasse Command/∗∗∗ This c l a s s i s part o f the ”World o f Zuul” app l i c a t i o n .∗ ”World o f Zuul” i s a very simple , t ex t based adventure

game .∗∗ This c l a s s ho lds in fo rmat ion about a command that was

i s su ed by the user .∗ A command cu r r en t l y c o n s i s t s o f two s t r i n g s : a command

word and a second∗ word ( f o r example , i f the command was ” take map” , then

the two s t r i n g s∗ obv ious ly are ” take ” and ”map”) .∗∗ The way t h i s i s used i s : Commands are a l r eady checked

f o r being va l i d∗ command words . I f the user entered an i n v a l i d command

( a word that i s not∗ known) then the command word i s <nul l >.∗

Page 99: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 92

∗ I f the command had only one word , then the second wordi s <nul l >.

∗∗ @author Michael Ko l l ing and David J . Barnes∗ @version 1 .0 ( February 2002)∗/

pub l i c c l a s s Command{

pr i va t e St r ing commandWord ;p r i va t e St r ing secondWord ;

/∗∗∗ Create a command ob j e c t . F i r s t and second word

must be suppl i ed , but∗ e i t h e r one ( or both ) can be nu l l . The command word

should be nu l l to∗ i n d i c a t e that t h i s was a command that i s not

r e cogn i s ed by t h i s game .∗/

pub l i c Command( St r ing f irstWord , S t r ing secondWord ){

commandWord = f i rs tWord ;t h i s . secondWord = secondWord ;

}

/∗∗∗ Return the command word ( the f i r s t word ) o f t h i s

command . I f the∗ command was not understood , the r e s u l t i s nu l l .∗/

pub l i c S t r ing getCommandWord ( ){

re turn commandWord ;}

/∗∗∗ Return the second word o f t h i s command . Returns

nu l l i f the re was no∗ second word .∗/

pub l i c S t r ing getSecondWord ( ){

re turn secondWord ;}

/∗∗∗ Return true i f t h i s command was not understood .∗/

pub l i c boolean isUnknown ( )

Page 100: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 93

{re turn (commandWord == nu l l ) ;

}

/∗∗∗ Return true i f the command has a second word .∗/

pub l i c boolean hasSecondWord ( ){

re turn ( secondWord != nu l l ) ;}

}

Listing 7.5: klasse CommandWords/∗∗∗ This c l a s s i s part o f the ”World o f Zuul” app l i c a t i o n .∗ ”World o f Zuul” i s a very simple , t ex t based adventure

game .∗∗ This c l a s s ho lds an enumeration o f a l l command words

known to the game .∗ I t i s used to r e c ogn i s e commands as they are typed in .∗∗ @author Michael Ko l l ing and David J . Barnes∗ @version 1 .0 ( February 2002)∗/

pub l i c c l a s s CommandWords{

// a constant array that ho lds a l l v a l i d commandwords

p r i va t e s t a t i c f i n a l S t r ing [ ] validCommands = {”go” , ” qu i t ” , ” he lp ” , ” look ” , ” eat ” , ”back” , ”

name” ,” get ” , ”drop” , ” items ”

} ;

/∗∗∗ Constructor − i n i t i a l i s e the command words .∗/

pub l i c CommandWords( ){

// nothing to do at the moment . . .}

/∗∗∗ Check whether a g iven St r ing i s a va l i d command

word .∗ Return true i f i t i s , f a l s e i f i t i s n ’ t .∗/

Page 101: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 94

pub l i c boolean isCommand( St r ing aSt r ing ){

f o r ( i n t i = 0 ; i < validCommands . l ength ; i++) {i f ( validCommands [ i ] . equa l s ( aSt r ing ) )

re turn true ;}// i f we get here , the s t r i n g was not found in

the commandsre turn f a l s e ;

}

/∗∗∗ Print a l l v a l i d statements∗/

pub l i c void showAll ( ){

f o r ( i n t i = 0 ; i < validCommands . l ength ; i++){

System . out . p r i n t ( validCommands [ i ] + ” ” ) ;}System . out . p r i n t l n ( ) ;

}

/∗∗∗ Return a l l v a l i d statements in a St r ing∗∗ @return St r ing [ ] validCommands A St r ing array

conta in ing∗ a l l v a l i d commands∗/

pub l i c S t r ing [ ] getCommandList ( ){

re turn validCommands ;}

}

Listing 7.6: klasse Roomimport java . u t i l . HashMap ;import java . u t i l . I t e r a t o r ;import java . u t i l . Set ;import java . u t i l . ArrayList ;

/∗∗ Class Room − a room in an adventure game .∗∗ This c l a s s i s part o f the ”World o f Zuul” app l i c a t i o n .∗ ”World o f Zuul” i s a very simple , t ex t based adventure

game .∗

Page 102: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 95

∗ A ”Room” r ep r e s en t s one l o c a t i o n in the scenery o f thegame . I t i s

∗ connected to other rooms v ia e x i t s . The e x i t s arel a b e l l e d north ,

∗ east , south , west . For each d i r e c t i on , the rooms t o r e s a r e f e r e n c e

∗ to the ne ighbor ing room , or nu l l i f the re i s no e x i tin that d i r e c t i o n .

∗∗ @author Michael Ko l l ing and David J . Barnes∗ Marti jn Hemeryck∗ @version 2 .0 (2006−04−13)∗/

pub l i c c l a s s Room{

pr i va t e St r ing d e s c r i p t i o n ;p r i va t e HashMap e x i t s ;// a hashmap f o r g e t t i n g items v ia S t r i ng s

p r i va t e HashMap items ;

/∗∗∗ Create a room desc r ibed ” d e s c r i p t i o n ” . I n i t i a l l y ,

i t has∗ no e x i t s . ” d e s c r i p t i o n ” i s something l i k e ”a

k i tchen ” or∗ ”an open court yard ” .∗/

pub l i c Room( St r ing d e s c r i p t i o n ){

t h i s . d e s c r i p t i o n = de s c r i p t i o n ;e x i t s = new HashMap( ) ;// i n i t i a l i s e s the itemMap

items = new HashMap( ) ;}

/∗∗∗ Def ine the e x i t s o f t h i s room . Every d i r e c t i o n

e i t h e r l e ad s∗ to another room or i s nu l l ( no e x i t the re ) .∗/

pub l i c void s e tEx i t ( S t r ing d i r e c t i on , Room neighbour ){

e x i t s . put ( d i r e c t i on , neighbour ) ;}

/∗∗∗ Accessor f o r r e tu rn ing the e x i t s∗/

pub l i c Room getEx i t ( S t r ing d i r e c t i o n )

Page 103: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 96

{re turn (Room) e x i t s . get ( d i r e c t i o n ) ;

}

/∗∗∗ Return a St r ing conta in ing the e x i t s to a g iven

space∗ f o r example ” Exi t s : north , west ” .∗/

pub l i c S t r ing ge tEx i tS t r i ng ( ){

St r ing r e tu rnS t r i ng = ” Exit s : ” ;Set keys = e x i t s . keySet ( ) ;f o r ( I t e r a t o r i t e r = keys . i t e r a t o r ( ) ; i t e r . hasNext

( ) ; ){

r e tu rnS t r i ng += ” ” + i t e r . next ( ) ;}re turn r e tu rnS t r i ng ;

}

/∗∗∗ Return the d e s c r i p t i o n o f the room ( the one that

was de f ined∗ in the cons t ruc to r ) .∗ @return St r ing d e s c r i p t i o n The d e s c r i p t i o n o f the

room∗/

pub l i c S t r ing ge tDe s c r i p t i on ( ){

re turn d e s c r i p t i o n ;}

/∗∗∗ Return a St r ing conta in ing the items in a room∗ f o r example : p r o j e c t o r∗ @return St r ing r e tu rnS t r i ng The St r ing conta in ing

the d e s c r i p t i o n o f the item∗/

pub l i c S t r ing get I t emStr ing ( ){

St r ing r e tu rnS t r i ng = ” Items : ” ;Set keys = items . keySet ( ) ;f o r ( I t e r a t o r i t e r = keys . i t e r a t o r ( ) ; i t e r . hasNext

( ) ; ){

r e tu rnS t r i ng += ” ” + i t e r . next ( ) ;}re turn r e tu rnS t r i ng ;

}

Page 104: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 97

/∗∗∗ Contains o f mapping o f the Items as ob j e c t s

and as St r ing∗ @param Str ing i t emDesc r ip t i on The d e s c r i p t i o n

o f the Item as St r ing∗ @param Item item The ac tua l item−ob j e c t∗/

pub l i c void addItem ( St r ing i temDescr ipt ion , Itemitem )

{i tems . put ( i temDescr ipt ion , item ) ;

}

/∗∗∗ Remove an item from the l i s t o f i tems∗ @param Str ing i t emDesc r ip t i on The key f o r

which you want to d e l e t e the value∗/

pub l i c void removeItem ( St r ing i t emDesc r ip t i on ){

i tems . remove ( i t emDesc r ip t i on ) ;}

/∗∗∗ Get the Item∗ @param Str ing i t emDesc r ip t i on The d e s c r i p t i o n

o f the item∗ @return Item item The HashMap l i n k i n g item

de s c r i p t i o n and the items∗/

pub l i c Item getItem ( St r ing i t emDesc r ip t i on ){

re turn ( Item ) items . get ( i t emDesc r ip t i on ) ;}

/∗∗∗ Return a long d e s c r i p t i o n o f t h i s room in the

f o l l ow i ng s t y l e :∗ You are in the k i t chen .∗ Exit s : north west∗ Items : p r o j e c t o r∗/

pub l i c S t r ing getLongDescr ipt ion ( ){

re turn ”You are ” + de s c r i p t i o n + ” .\n” +ge tEx i tS t r i ng ( ) + ” .\n” + get I temStr ing ( ) ;

}}

Page 105: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 98

Listing 7.7: klasse Parserimport java . i o . BufferedReader ;import java . i o . InputStreamReader ;import java . u t i l . S t r ingToken i ze r ;

/∗∗ This c l a s s i s part o f the ”World o f Zuul” app l i c a t i o n .∗ ”World o f Zuul” i s a very simple , t ex t based adventure

game .∗∗ This par s e r reads user input and t r i e s to i n t e r p r e t i t

as an ”Adventure”∗ command . Every time i t i s c a l l e d i t reads a l i n e from

the te rmina l and∗ t r i e s to i n t e r p r e t the l i n e as a two word command . I t

r e tu rn s the command∗ as an ob j e c t o f c l a s s Command.∗∗ The par s e r has a s e t o f known command words . I t checks

user input aga in s t∗ the known commands , and i f the input i s not one o f the

known commands , i t∗ r e tu rn s a command ob j e c t that i s marked as an unknown

command .∗∗ @author Michael Ko l l ing and David J . Barnes∗ Marti jn Hemeryck∗ @version 2 .0 (2006−04−13)∗/

pub l i c c l a s s Parser{

pr i va t e CommandWords commands ; // ho lds a l l v a l i dcommand words

pub l i c Parser ( ){

commands = new CommandWords( ) ;}

pub l i c Command getCommand ( ){

St r ing inputLine = ”” ; // w i l l hold the f u l linput l i n e

St r ing word1 ;S t r ing word2 ;

System . out . p r i n t ( ”> ” ) ; // p r in t prompt

Page 106: Oplossingen Methodiek van de Informatica

HOOFDSTUK 7. KLASSEN ONTWERPEN 99

BufferedReader reader =new BufferedReader (new InputStreamReader (

System . in ) ) ;t ry {

inputLine = reader . readLine ( ) ;}catch ( java . i o . IOException exc ) {

System . out . p r i n t l n ( ”There was an e r r o rduring read ing : ”

+ exc . getMessage ( ) ) ;}

Str ingToken ize r t ok en i z e r = new Str ingToken ize r (inputLine ) ;

i f ( t ok en i z e r . hasMoreTokens ( ) )word1 = token i z e r . nextToken ( ) ; // get

f i r s t worde l s e

word1 = nu l l ;i f ( t ok en i z e r . hasMoreTokens ( ) )

word2 = token i z e r . nextToken ( ) ; // getsecond word

e l s eword2 = nu l l ;

// note : we j u s t i gno re the r e s t o f the inputl i n e .

// Now check whether t h i s word i s known . I f so ,c r e a t e a command

// with i t . I f not , c r e a t e a ” nu l l ” command ( f o runknown command) .

i f ( commands . isCommand(word1 ) )re turn new Command(word1 , word2 ) ;

e l s ere turn new Command( nul l , word2 ) ;

}

/∗∗∗ Print a l i s t conta in ing a l l the va l i d commands∗/

pub l i c S t r ing [ ] showCommands ( ){

re turn commands . getCommandList ( ) ;}

}

Page 107: Oplossingen Methodiek van de Informatica

Hoofdstuk 8

De structuur verbeterenmet overerving

Oefening 8.1 Een voorbeeld van een print ziet er als volgt uit

Listing 8.1: een voorbeeldlijstje voor het project DoMECD: Tour i s t (70 mins )

St . Germain

t ra ck s : 11

<no comment>

video : I c h i the k i l l e r (120 mins )

K in j i Fukusaku

<no comment>

Oefening 8.2 Bij het opnieuw afdrukken van de informatie zal de commentaarer bij staan. Dit is zo omdat de het Database-object een verwijzing naar eenArrayList bijhoudt die op haar beurt een verwijzing naar ons object, onze cdbijhoudt. Bij het aanpassen van een van de attributen van dat object wordtgewijzigde informatie ook doorgegeven. Deze onderlinge verbanden zijn goed tezien in de object-inspector van BlueJ.

Oefening 8.3

Oefening 8.4 Bij het verwijderen van de woordcombinatie extends Item verd-wijnt het pijltje van Video naar Item wat er op wijst dat Video nu niet langermeer een subklasse is van Item.

100

Page 108: Oplossingen Methodiek van de Informatica

HOOFDSTUK 8. DE STRUCTUUR VERBETEREN MET OVERERVING101

Figuur 8.1: Een overervingshierarchie voor de leden aan een universiteit

Oefening 8.5 Een geerfde methode zoals print geeft niet meer langer de arti-est van de cd-terug. De methode maakt namelijk alleen maar gebruik van deattributen van een hoger gelegen klasse.

Oefening 8.6 Bij het uitvoeren van de constructor zien we dat in de regel waareen super-oproep staat dat de constructor van de superklasse wordt aangespro-ken (Item in ons geval). Nadat die constructor is uitgevoerd wordt de rest vande constructor nog uitgevoerd (die van de klasse CD hier).

Listing 8.2: klasse VideoGame

/∗∗∗ Represents a videogame∗∗ @author Mart i jn Hemeryck∗ @version 0 .1 2006−04−27∗/

pub l i c c l a s s VideoGame extends Game{

pr i va t e St r ing plat form ;

/∗∗∗ Constructor f o r ob j e c t s o f c l a s s VideoGame∗/

pub l i c VideoGame( St r ing t i t l e , i n t playingTime ,i n t numberOfPlayers , S t r ing plat form )

{

Page 109: Oplossingen Methodiek van de Informatica

HOOFDSTUK 8. DE STRUCTUUR VERBETEREN MET OVERERVING102

super ( t i t l e , playingTime , numberOfPlayers ) ;t h i s . p lat form = plat form ;

}

}

Figuur 8.2: Een overervingshierarchie voor voedingsmiddelen

Oefening 8.8

Oefening 8.9 We zouden kunnen stellen dat beiden muis en touchpad eenmanier zijn voor een gebruiker om te interageren met een PC d.m.v. een cursor.Cursor en Muis zouden dan subklassen zijn van een superklasse Pointer of ietsdergelijks.

Oefening 8.10 Een vierkant is een speciaal geval van een rechthoek. Wekunnen een vierkant dus zien als een subklasse van een rechthoek. Later zullenwe zien dat deze visie wel niet volledig is1.

Oefening 8.11 Toegestane statements:

Person p1 = new Student ( ) ;Person p2 = new PhDStudent ( ) ;Teacher t1 = new Person ( ) ;

1zie blz. 143

Page 110: Oplossingen Methodiek van de Informatica

HOOFDSTUK 8. DE STRUCTUUR VERBETEREN MET OVERERVING103

Student s1 = new PhDStudent ( ) ;

s1 = p1 ;p1 = s1 ;phd1 = s1 ;

Oefening 8.13 Aangezien we werken met polymorfe variabelen moeten weniets veranderen aan de klasse Database als we een subklasse toevoegen aan deklasse Item. Dit in feite de kracht van het principe overerving.

Oefening 8.14 Een overzicht van alle standaardklassen kan in de API gevon-den worden.

Oefening 8.15 De verschillende klassen bewerkt uit het lab-class project

Listing 8.3: klasse Person

/∗∗∗ Represents a person∗∗ @author Mart i jn Hemeryck∗ @version 0 .1 2006−04−27∗/

pub l i c c l a s s Person{

pr i va t e St r ing name ;p r i va t e St r ing id ;

/∗∗∗ Constructor f o r ob j e c t s o f c l a s s Person∗/

pub l i c Person ( St r ing name , S t r ing id ){

t h i s . name = name ;t h i s . id = id ;

}

/∗∗∗ Return the f u l l name .∗/

pub l i c S t r ing getName ( ){

re turn name ;}

/∗∗∗ Set a new name f o r t h i s student .∗/

pub l i c void changeName ( St r ing replacementName )

Page 111: Oplossingen Methodiek van de Informatica

HOOFDSTUK 8. DE STRUCTUUR VERBETEREN MET OVERERVING104

{name = replacementName ;

}

/∗∗∗ Return the ID o f t h i s student .∗/

pub l i c S t r ing getID ( ){

re turn id ;}

/∗∗∗ Return the l o g i n name . The l o g i n name i s a

combination∗ o f the f i r s t f our cha ra c t e r s o f the name and the

f i r s t three∗ cha ra c t e r s o f the ID number .∗/

pub l i c S t r ing getLoginName ( ){

re turn name . sub s t r i ng (0 , 4 ) + id . sub s t r i ng (0 , 3 ) ;}

/∗∗∗ Print the name and ID number to the output

te rmina l .∗/

pub l i c void p r in t ( ){

System . out . p r i n t l n (name + ” ( ” + id + ” ) ” ) ;}

}

Listing 8.4: klasse Student

/∗∗∗ The Student c l a s s r ep r e s en t s a student in a student

admin i s t r a t i on system .∗ I t ho lds the student d e t a i l s r e l e van t in our context .∗∗ @author Michael Ko l l ing and David Barnes∗ @version 2001 .05 .24∗/

pub l i c c l a s s Student extends Person{

// the amount o f c r e d i t s f o r study taken so f a rp r i va t e i n t c r e d i t s ;

/∗∗

Page 112: Oplossingen Methodiek van de Informatica

HOOFDSTUK 8. DE STRUCTUUR VERBETEREN MET OVERERVING105

∗ Create a new student with a given name and IDnumber .

∗/pub l i c Student ( S t r ing name , S t r ing id ){

super (name , id ) ;c r e d i t s = 0 ;

}

/∗∗∗ Add some c r e d i t po in t s to the student ’ s

accumulated c r e d i t s .∗/

pub l i c void addCredits ( i n t add i t i ona lPo in t s ){

c r e d i t s += add i t i ona lPo in t s ;}

/∗∗∗ Return the number o f c r e d i t po in t s t h i s student

has accumulated .∗/

pub l i c i n t g e tCred i t s ( ){

re turn c r e d i t s ;}

}

Listing 8.5: klasse Docent

/∗∗∗ Represents a teacher∗∗ @author Mart i jn Hemeryck∗ @version 0 .1 2006−04 27∗/

pub l i c c l a s s Docent extends Person{

pr i va t e i n t wage ;

/∗∗∗ Constructor f o r ob j e c t s o f c l a s s Docent∗/

pub l i c Docent ( S t r ing name , S t r ing id , i n t wage ){

super (name , id ) ;t h i s . wage = wage ;

}

/∗∗

Page 113: Oplossingen Methodiek van de Informatica

HOOFDSTUK 8. DE STRUCTUUR VERBETEREN MET OVERERVING106

∗ Sets the wage f o r a docent∗/

pub l i c void setWage ( i n t wage ){

t h i s . wage = wage ;}

/∗∗∗ Returns the wage o f a docent∗/

pub l i c i n t getWage ( ){

re turn wage ;}

}

Figuur 8.3: Een overervingshierarchie voor gegeven code

Oefening 8.17

Page 114: Oplossingen Methodiek van de Informatica

Hoofdstuk 9

Meer over overerving

Oefening 9.1 Als we de methode simpelweg verplaatsen van Item naar Videokrijgen we een compileerfout aangezien een aantal attributen die gebruikt wor-den in deze methode private gedeclareerd staan in Item.

Oefening 9.2 Als we een aparte methode print maken in de subklasse (bi-jvoorbeeld in CD), dan zal bij het uitvoeren van de methode list uit Databasede methode print van de laagst gelegen subklasse opgeroepen worden. Dezetechniek wordt overschrijven genoemd of method overloading.

Listing 9.1: klasse CD/∗∗∗ The CD c l a s s r ep r e s en t s a CD ob j e c t . In format ion about

the∗ CD i s s to r ed and can be r e t r i e v e d .∗∗ @author Michael Ko l l ing and David J . Barnes∗ Marti jn Hemeryck∗ @version 2006−04−28∗/

pub l i c c l a s s CD extends Item{

pr i va t e St r ing a r t i s t ;p r i va t e i n t numberOfTracks ;

/∗∗∗ Constructor f o r ob j e c t s o f c l a s s CD∗/

pub l i c CD( St r ing theTi t l e , S t r ing theArt i s t , i n tt racks , i n t time )

{super ( theTi t l e , time ) ;a r t i s t = theAr t i s t ;numberOfTracks = t rack s ;

}

107

Page 115: Oplossingen Methodiek van de Informatica

HOOFDSTUK 9. MEER OVER OVERERVING 108

/∗∗∗ Return the a r t i s t f o r t h i s CD.∗/

pub l i c S t r ing g e tAr t i s t ( ){

re turn a r t i s t ;}

/∗∗∗ Return the number o f t r a ck s on t h i s CD.∗/

pub l i c i n t getNumberOfTracks ( ){

re turn numberOfTracks ;}

/∗∗∗ Pr int s the name o f the a r t i s t∗/

pub l i c void p r in t ( ){

System . out . p r i n t l n ( ”CD: ” ) ;super . p r i n t ( ) ;System . out . p r i n t l n ( ” ” + a r t i s t ) ;System . out . p r i n t l n ( ” t ra ck s : ” +

numberOfTracks ) ;}

}

Listing 9.2: klasse Video/∗∗∗ The Video c l a s s r ep r e s en t s a video ob j e c t . In format ion

about the∗ video i s s to r ed and can be r e t r i e v e d .∗∗ @author Michael Ko l l ing and David J . Barnes∗ Marti jn Hemeryck∗ @version 2006−04−28∗/

pub l i c c l a s s Video extends Item{

pr i va t e St r ing d i r e c t o r ;

/∗∗∗ Constructor f o r ob j e c t s o f c l a s s Video∗/

pub l i c Video ( S t r ing theTi t l e , S t r ing theDirec tor , i n ttime )

{

Page 116: Oplossingen Methodiek van de Informatica

HOOFDSTUK 9. MEER OVER OVERERVING 109

super ( theTi t l e , time ) ;d i r e c t o r = theDi r e c to r ;

}

/∗∗∗ Return the d i r e c t o r f o r t h i s v ideo .∗/

pub l i c S t r ing ge tD i r e c t o r ( ){

re turn d i r e c t o r ;}

/∗∗∗ Pr int s the d e t a i l s o f t h i s v ideo∗/

pub l i c void p r in t ( ){

System . out . p r i n t l n ( ”Video ” ) ;super . p r i n t ( ) ;System . out . p r i n t l n ( ” ” + d i r e c t o r ) ;

}}

Oefening 9.5 De methode toString heeft geen parameters nodig. Het return-type is een String.

Oefening 9.7 Deze wijziging werd reeds doorgevoerd in oefeningen 9.3 en 9.4,zie code 9.1.

Listing 9.3: klasse MagicRoom uit zuul-better

/∗∗∗ A magic room∗ I f a p laye r en t e r s t h i s room , he/ she w i l l be

t r a n s f e r r e d to another∗ randomly chosen room∗∗ @author Mart i jn Hemeryck∗ @version 2006−04−28∗/

pub l i c c l a s s MagicRoom extends Room{

/∗∗∗ Constructor f o r ob j e c t s o f c l a s s MagicRoom∗/

pub l i c MagicRoom( St r ing d e s c r i p t i o n )

Page 117: Oplossingen Methodiek van de Informatica

HOOFDSTUK 9. MEER OVER OVERERVING 110

{super ( d e s c r i p t i o n ) ;

}

/∗∗∗ Return a random room , independent o f the

parameter d i r e c t i o n∗∗ @param Str ing d i r e c t i o n The d i r e c t i o n the

p laye r wants to head f o r∗ @return Room findRandomRoom A randomly chosen

Room∗/

pub l i c Room getEx i t ( S t r ing d i r e c t i o n ){

re turn findRandomRoom ( ) ; // dec l a r ed ins up e r c l a s s

}}

Oefening 9.10 We kunnen voor beiden speler en monster een gemeenschap-pelijk superklasse Character bedenken die de gemeenschappelijke kenmerken(attributen) bijhoudt van een speler en monster.

Oefening 9.11 Een speler kan een voorwerp met zich meenemen maar deeltnormaal gezien geen eigenschappen (attributen) noch methodes met een voor-werp. In die zin is er geen duidelijk relatie in termen van inheritance tussen detwee klassen.

Oefening 9.12 Om te kunnen compileren moet de klasse Device zeker eenmethode getName hebben aangezien dat het statische type is van het objectdev. Het is echter ook toegestaan om daarbij nog een methode getName teschrijven in de klasse Printer die dan de methode van de subklasse overschrijft.

Oefening 9.13 In het geval dat de klasse Printer ook een methode getNamebevat zal deze gebruikt worden bij het uitvoeren van het programma.

Oefening 9.14 Deze regels zullen normaliter moeten compileren aangezien demethode toString een methode is van de klasse Object. Aangezien alle klassenin JAVA subklassen zijn van de klasse object is deze methode bijgevolg ookbekend in al deze subklassen. Wanneer we dus zelf geen implementatie gevenvoor de methode Object (dus niet de methode van de superklasse overschrijven),dan zal gewoon de implementatie van de hoger gelegen klasse gebruikt worden.

Oefening 9.15 Deze regels moeten normaal gezien ook compileren daar we viaSystem.out.println() automatisch een oproep doen naar de methode toString.

System . out . p r i n t l n ( s t ) ;

Page 118: Oplossingen Methodiek van de Informatica

HOOFDSTUK 9. MEER OVER OVERERVING 111

is dus equivalent met

System . out . p r i n t l n ( s t . t oS t r i ng ( ) ) ;

Oefening 9.16 Hoewel ik dit niet heb getest ga ik er van uit dat deze lijnencode ook moeten compileren. We doen nl. net hetzelfde als in de vorige oefening,met dat verschil dat nu niet langer de methode toString van de klasse Objectwordt gebruikt maar deze van de klasse Student, onze eigen implementatie vande methode.

Listing 9.4: oef 9.17T X = new D( ) ;

Page 119: Oplossingen Methodiek van de Informatica

Hoofdstuk 10

Technieken voor verdereabstractie

Oefening 10.1 Het aantal vossen zal veranderen als je een simulatiestap door-loopt.

Oefening 10.2 Bij het doorlopen van een verschillend aantal stappen zullenwe zien dat er steeds schommelingen zijn in de verhouding vossen/konijnen: hetene moment zullen er meer vossen dan konijnen zijn, het andere moment hetomgekeerde geval. Er kunnen veel oorzaken zijn voor dit fenomeen, waaronderook een aantal externe factoren waar hier geen rekening mee wordt gehouden(ziekte binnen een bepaalde populatie, . . . ).

Oefening 10.3 Een echte evenredigheid is niet op te merken, enkel schom-melingen in het evenwicht.

Oefening 10.4 Bij verschillende keren laten doorlopen van de lange simulatie(500 stappen), blijkt dat er keren zijn waar de vossenpopulatie op 0 komt testaan.

Oefening 10.5 Het verloop van de gebeurtenissen is niet identiek aan devorige simulatie, doch dezelfde schommelingen in de verhouding van de popu-laties is wel zichtbaar.

Oefening 10.6 Als we veronderstellen dat de vossen alleen kunnen overlevendoor konijnen te eten en de populatie van de konijnen zou uitsterven, dan zouhet in principe mogelijk kunnen zijn dat de beide populaties uitsterven. Inhet geval dat de vossen uitsterven en de konijnen niet zal de populatie van dekonijnen aanvankelijk zelfs kunnen toenemen, doch op langere termijn zich tochstabiliseren (convergeren) rond een bepaalde waarde1.

1Zoals ooit gezien in een voorbeeld in de cursus Analyse 1

112

Page 120: Oplossingen Methodiek van de Informatica

HOOFDSTUK 10. TECHNIEKEN VOOR VERDERE ABSTRACTIE 113

Oefening 10.7 Als de overlevingskansen voor een ram en een voedster ver-schillend zijn (wat waarschijnlijk ook zo het geval is), dan is dit inderdaad eentekortkoming van het model.

Oefening 10.8 Een aantal externe factoren zijn niet in rekening gebracht,zoals het voedsel waar de konijnen zelf van overleven, het milieu waarin dekonijnen overleven, ziektes, . . . . Daarbij wordt er ook geen rekening gehoudenmet het feit dat, wanneer de populatie te groot wordt, de middelen om teoverleven voor ieder individueel lid van de populatie kleiner wordt. Zo zal erniet meer genoeg voedsel zijn voor ieder konijn naarmate de gehele populatiekonijnen te groot wordt.

Oefening 10.9 Wanneer we bijvoorbeeld de statische variabele BREEDING PROBABILITYinstellen op 0.50, zien we dat de schommelingen in het evenwicht tussen de

verschillende populaties nog groter zijn.

Oefening 10.10 Aangezien we hier ook weer een aantal gelijkaardige vereen-voudigingen hebben kunnen we ook tot een aantal gelijkaardige conclusies komen.Een ander voorbeeld van een vereenvoudiging hier gebruikt is dat we, aangezienwe geen onderscheid op basis van geslacht hebben, dat er ook geen drachtperi-ode voor de vrouwelijke leden van de populatie in rekening is gebracht terwijlhet gedrag van zo’n lid best wel eens anders kon zijn dan hier gemodelleerd.

Oefening 10.11-10.15 Aangezien de maximale leeftijd voor de vossenpopu-latie aanvankelijk al stond ingesteld op de toch wel onrealistische waarde van150 jaar, zal het effect van het nog verhogen van deze leeftijd niet zo groot zijn.Dit zien we ook als we dit daadwerkelijk veranderen in de source code en eensimulatie laten lopen2.

Oefening 10.16 Met het aanpassen van de methode simulate wordt bedoelddat we bij het aanmaken van een konijn dit als volgt doen:

Rabbit rabb i t = new Rabbit ( f a l s e ) ;

Bij het uitvoeren van een simulatie zien we nu dat de verhoudingen tussenvossen en konijnen een meer vast patroon vormen. Ook zien we dat uiteindelijkde populatie van konijnen de overhand zal halen aangezien een van de populatiesvroegtijdig eindigt.

Oefening 10.17 De vossenpopulatie zal minder plaats hebben om zich voortte planten en zich uit breiden als het de leeftijd bereikt heeft om zich te kunnenvoortplanten als in het andere geval. In dat opzicht zullen de verhoudingen vande populaties dus verschillend zijn3.

2De oefeningen 10.12 tot 10.15 worden hier niet besproken aangezien ze in feite alleenbetrekking hebben tot het specifieke voorbeeld hier aangehaald en feite niet zo veel overzeggen over de principes die in dit hoofdstuk zitten. Meer uitleg is trouwens ook te vinden opslides van de bijhorend hoorcolleges (op Toledo).

3Het feit dat we gebruik maken van random-leeftijden zal wel verschillende redenen hebben.Ten eerste is dit model algemener aangezien het niet uitgaat van bestaande data over deleeftijdsverdeling van een populatie - wat het ook onnauwkeuriger maakt. Daarnaast hoeven

Page 121: Oplossingen Methodiek van de Informatica

HOOFDSTUK 10. TECHNIEKEN VOOR VERDERE ABSTRACTIE 114

Oefening 10.18 De vossen verliezen het voordeel wat ze hadden t.o.v. dekonijnen of de konijnen kunnen zich nu makkelijker en sneller voortplantenaangezien ze voor hun voortplanting geen rekening meer hoeven te houden metof er zich al dan niet een vos bevindt in het gebied waar ze hun nakomelingenter wereld willen brengen. Dit betekent ook dat als er een konijn geboren wordtwaar er zich een vos bevindt, dat dit konijn de vos zal vervangen.

Oefening 10.19 Om dit te kunnen onderzoeken moeten we de methodes hunten findFood van Fox onderzoeken. We zien hierbij dat er voor het bepalen

van de richting waar een vos naar toe moet gaan, de vos zich enkel maarop nieuwe locatie kan bevinden als deze vrij is. De oproep van de methodefreeAdjacentLocation van de klasse Field garandeert dit.

i f ( newLocation == nu l l ){newLocation = updatedFie ld . f r e eAdjecentLocat i on ( l o c a t i o n )

;}

Oefening 10.20-10.21 De voornaamste overeenkomsten:

• gemeenschappelijke attributen

– age

– alive

– location

• gemeenschappelijk methodes

– act ter vervanging van run en hunt

Oefening 10.22 Neen, we kijken bij het beoordelen of een klassevariabele aldan niet identiek is aan een andere klassevariabele enkel naar de functionaliteitdie deze klassevariabele vervult. Een waarde kan namelijk veranderd wordenen via het idee van overerving worden aanpassingen in deze waarden doorgaansook makkelijker.

Listing 10.1: klasse Animalimport java . u t i l .Random ;

/∗∗∗ Represents an animal ( fox , rabbit , e t c . . . . )∗∗ @author Mart i jn Hemeryck∗ @version 2006−04−29∗/

we ook geen rekening te houden met het transient gedrag van de populaties, maar wordt desteady state makkelijker bereikt - wat uiteindelijk hetgene is wat we willen onderzoeken

Page 122: Oplossingen Methodiek van de Informatica

HOOFDSTUK 10. TECHNIEKEN VOOR VERDERE ABSTRACTIE 115

pub l i c c l a s s Animal{

// Cha r a c t e r i s t i c s shared by a l l animals ( s t a t i cf i e l d s ) .

// The age at which a rabb i t can s t a r t to breed .p r i va t e s t a t i c f i n a l i n t BREEDING AGE = 0 ;// The age to which a rabb i t can l i v e .p r i va t e s t a t i c f i n a l i n t MAXAGE = 0 ;// The l i k e l i h o o d o f a rabb i t breed ing .p r i va t e s t a t i c f i n a l double BREEDING PROBABILITY =

0 . 0 ;// The maximum number o f b i r t h s .p r i va t e s t a t i c f i n a l i n t MAX LITTER SIZE = 0 ;// A shared random number generator to c on t r o l

breed ing .p r i va t e s t a t i c f i n a l Random rand = new Random( ) ;

// Ind i v i dua l c h a r a c t e r i s t i c s ( i n s t anc e f i e l d s ) .

// The animal ’ s age .pro tec ted i n t age ;// Whether the animal i s a l i v e or not .p ro tec ted boolean a l i v e ;// The animal ’ s p o s i t i o nprotec ted Locat ion l o c a t i o n ;

/∗∗∗ Constructor f o r ob j e c t s o f c l a s s Animal∗/

pub l i c Animal ( boolean randomAge ){

age = 0 ;a l i v e = true ;i f ( randomAge ) {

age = rand . next Int (MAXAGE) ;}

}

/∗∗∗ Check whether the animal i s a l i v e or not .∗ @return True i f the animal i s s t i l l a l i v e .∗/

pub l i c boolean i sA l i v e ( ){

re turn a l i v e ;}

/∗∗∗ Set the animal ’ s l o c a t i o n .

Page 123: Oplossingen Methodiek van de Informatica

HOOFDSTUK 10. TECHNIEKEN VOOR VERDERE ABSTRACTIE 116

∗ @param row The v e r t i c a l coo rd inate o f the l o c a t i o n.

∗ @param co l The ho r i z on t a l coo rd inate o f thel o c a t i o n .

∗/pub l i c void s e tLocat i on ( i n t row , i n t c o l ){

t h i s . l o c a t i o n = new Locat ion ( row , c o l ) ;}

/∗∗∗ Set the animal ’ s l o c a t i o n .∗ @param l o c a t i o n The animal ’ s l o c a t i o n .∗/

pub l i c void s e tLocat i on ( Locat ion l o c a t i o n ){

t h i s . l o c a t i o n = l o c a t i o n ;}

/∗∗∗ Te l l the animal that i t ’ s dead now : (∗/

pub l i c void setDead ( ){

a l i v e = f a l s e ;}

}

Oefening 10.25 Een direct gevolg van de voorgaande aanpassingen is dat wegemakkelijk andere dieren nu kunnen aanmaken en dat bepaalde code niet iniedere subklasse meer dient overgenomen te worden. Ook wordt het oproepenvan de attributen van de klassen gemakkelijker voor andere klassen (in Simulatorbijvoorbeeld).

Oefening 10.26 Voorheen maakten we gebruik van de operator instanceofom te kijken van welke klasse een bepaald object was. Hierbij konden we dusobjecten doorgeven van iedere klasse die we wilden (dus alle objecten van deklasse Object). Als de test faalde werd gewoon het else statement uitgevoerd.

Nu doen we voor onze lus een oproep naar een methode uit de klasse Animal, waarbij we dus beperken op het aantal objecten dat kan worden meegegevenaan de lus. Deze lus werkt nu ook niet meer met de types Fox en Rabbit maardat is geen probleem aangezien deze toch subtypes zijn van Animal.

Oefening 10.27 We kunnen deze best toch abstract definieren willen we zekerzijn dat er nooit objecten van deze klasse zullen aangemaakt worden. Stel datde klasse niet abstract zou zijn en de methodes wel, dan kan er voor een objectvan die klasse (met die klasse als dynamisch en statisch type) de methodes vandie klasse niet uitgevoerd worden.

Page 124: Oplossingen Methodiek van de Informatica

HOOFDSTUK 10. TECHNIEKEN VOOR VERDERE ABSTRACTIE 117

Oefening 10.28 Het is mogelijk om voor een abstracte klasse een concretemethode te implementeren. Bij het uitvoeren van het programma zal voor eenobject toch altijd de methode van het dynamische type worden uitgevoerd (dusvan de laagst gelegen subklasse). Dit is echter af te raden voor een aantalredenen:

• Aangezien de methode in de abstracte klasse staat kunnen er geen ob-jecten worden aangemaakt van deze klasse en zal de concrete methodein deze klasse toch nooit kunnen worden aangesproken door objecten vandeze klasse zelf (dynamisch/statisch type). In dit voorbeeld: de concretemethode zoals beschreven in Animal kan niet worden opgeroepen door eenobject dat als dynamisch en statisch type Animal aangezien er geen geenobject kan bestaan dat aan deze voorwaarden voldoet.

• Een van de voordelen van een abstracte methode in te voeren is dat je aanalle subklassen oplegt dat ze een implementatie hebben van deze methode.M.a.w.: de klasse Fox en Rabbit moeten een implementatie hebben vandeze methode

Oefening 10.29 Een schoolvoorbeeld van zo’n situatie is de abstracte klasseMath: ze bevat methodes die we kunnen uitvoeren maar we zullen nooit objectenkunnen aanmaken van de klasse zelf.

Oefening 10.30 In de eerste lijn van de commentaar staat altijd de headervan de klasse. Als er abstract in vermeld staat is het vrij duidelijk dat dit eenabstracte klasse is. Als een klasse een uitbreiding van een abstracte klasse iswordt dit aangegeven door implements.

Oefening 10.31 Om een abstracte methode als zodanig te herkennen kunnenwe dit ook terugvinden in de API door te kijken naar de header van de methode.

Voorbeeld:

pub l i c ab s t r a c t i n t s i z e ( )

Het is van belang om te weten welke methodes abstract zijn aangezien wedeze methodes moeten implementeren als we van plan zijn subklassen van dezeklasse te maken.

Oefening 10.32 Als we de objectdiagramma van de projecten foxes-and-rabbits-v1 en foxes-and-rabbits-v2 vergelijken zien we dat de klassen Field enLocation ook verbeterd kunnen worden.

Oefening 10.33 In hoofdstuk 9 worden in het handboek volgende regels metbetrekking tot method dispatching aangehaald:

• een object met als statisch type een bepaalde klasse en als dynamisch typediezelfde klasse kan een methode van die klasse uitvoeren. Dit kenden weook al voordat we over overerving spraken.

• een object met als statisch type een bepaalde klasse en als dynamisch typeeen subklasse van de klasse die als statisch type dient en waarvoor we eenbepaalde methode uitvoeren:

Page 125: Oplossingen Methodiek van de Informatica

HOOFDSTUK 10. TECHNIEKEN VOOR VERDERE ABSTRACTIE 118

– de laagst gelegen klasse heeft geen implementatie van deze methode,of, de klasse van het dynamisch type heeft geen implementatie vandeze methode: de methode van de superklasse wordt uitgevoerd.

– de laagst gelegen klasse heeft wel een implementatie van deze meth-ode, of, de klasse van het dynamisch type heeft een implementatievan deze methode: de methode van het dynamisch type wordt uit-gevoerd.

Dit kadert in de discussie van abstracte klassen doordat we ons voor eenabstracte klassen altijd in het laatst beschreven geval bevinden. Dit verklaartook waarom we voor subklassen van een abstracte klassen altijd opleggen datze een implementatie moeten hebben voor de abstracte methodes.

Oefening 10.34 We schrijven een klasse PopulationGenerator en passen demethode populate van Simulator aan. Een (niet-volledige doch werkend imple-mentatie) van PopulationGenerator zou dan zijn

Listing 10.2: klasse PopulationGeneratorimport java . u t i l .Random ;import java . u t i l . Co l l e c t i o n s ;import java . u t i l . L i s t ;

/∗∗∗ Generate a populat ion f o r the s imula tor∗∗ @author Mart i jn Hemeryck∗ @version 2006−04−29∗/

pub l i c c l a s s Populat ionGenerator{

// The p r obab i l i t y that a fox w i l l be c rea ted in anygiven g r id po s i t i o n .

p r i va t e s t a t i c f i n a l double FOX CREATION PROBABILITY= 0 . 0 2 ;

// The p r obab i l i t y that a rabb i t w i l l be c rea ted inany given g r id po s i t i o n .

p r i va t e s t a t i c f i n a l doubleRABBIT CREATION PROBABILITY = 0 . 0 8 ;

// The f i e l d in which the animals w i l l be putp r i va t e F i e ld f i e l d ;// The l i s t o f animals in the f i e l dp r i va t e L i s t animals ;

/∗∗∗ Constructor f o r ob j e c t s o f c l a s s

Populat ionGenerator∗/

pub l i c Populat ionGenerator ( F i e ld f i e l d , L i s t animals ){

Page 126: Oplossingen Methodiek van de Informatica

HOOFDSTUK 10. TECHNIEKEN VOOR VERDERE ABSTRACTIE 119

t h i s . f i e l d = f i e l d ;t h i s . animals = animals ;populate ( ) ;

}

/∗∗∗ Populate a f i e l d with f oxe s and rabb i t s .∗ @param f i e l d The f i e l d to be populated .∗/

p r i va t e void populate ( ){

Random rand = new Random( ) ;f i e l d . c l e a r ( ) ;f o r ( i n t row = 0 ; row < f i e l d . getDepth ( ) ; row++) {

f o r ( i n t c o l = 0 ; c o l < f i e l d . getWidth ( ) ; c o l++) {i f ( rand . nextDouble ( ) <=

FOX CREATION PROBABILITY) {Fox fox = new Fox( t rue ) ;fox . s e tLoca t i on ( row , c o l ) ;animals . add ( fox ) ;f i e l d . p lace ( fox ) ;

}e l s e i f ( rand . nextDouble ( ) <=

RABBIT CREATION PROBABILITY) {Rabbit rabb i t = new Rabbit ( t rue ) ;r abb i t . s e tLoca t i on ( row , c o l ) ;animals . add ( rabb i t ) ;f i e l d . p lace ( rabb i t ) ;

}// e l s e l e ave the l o c a t i o n empty .

}}Co l l e c t i o n s . s h u f f l e ( animals ) ;

}

/∗∗∗ Get the newly generated l i s t o f animals∗ @return L i s t animals The new l i s t o f animals∗/

pub l i c L i s t getAnimals ( ){

re turn animals ;}

/∗∗∗ Get the newly generated f i e l d with the animals∗ @return F i e ld f i e l d the new f i e l d∗/

pub l i c F i e ld g e tF i e l d ( )

Page 127: Oplossingen Methodiek van de Informatica

HOOFDSTUK 10. TECHNIEKEN VOOR VERDERE ABSTRACTIE 120

{re turn f i e l d ;

}}

In de klasse Simulator wordt de methode populate dan

/∗∗∗ Populate a f i e l d with f oxe s and rabb i t s .∗ @param f i e l d The f i e l d to be populated .∗/

p r i va t e void populate ( F i e ld f i e l d ){

Populat ionGenerator pg = new Populat ionGenerator (f i e l d , animals ) ;

animals = ( ArrayList ) pg . getAnimals ( ) ;f i e l d = ( F i e ld ) pg . g e tF i e l d ( ) ;

}

Oefening 10.35 De methode canBreed ziet er als volgt uit.

/∗∗∗ A fox can breed i f i t has reached the breed ing age .∗/

p r i va t e boolean canBreed ( ){

re turn getAge ( ) >= BREEDING AGE;}

Als we echter gaan kijken in de klassen Fox en Rabbit dan vinden we hiernergens een implementatie van getAge terug; m.a.w. wordt deze methodeovergenomen van de superklasse Animal. De reden waarom we deze methode inieder van de respectievelijke subklassen laat staan is omdat BREEDING AGEvoor ieder van de twee subklassen anders gedefinieerd is en dus een ander re-sultaat oplevert naar gelang het dynamisch type van het object. We zoudenwel bijvoorbeeld al een methode canBreed als abstracte methode kunnen in-geven in de klasse Animal teneinde er zeker van te zijn dat deze methode altijdgeımplementeerd wordt voor ieder dier.

Oefening 10.36 Het project zal niet dadelijk compileren voor de wijzigingendie besproken werden in het handboek. De methode getBreedingAge() is nl.niet gekend in de klasse Animal; vandaar dat we nog een abstracte methodegetBreedingAge() definieren in de klasse Animal. De methode canBreed moetdaarbij ook protected worden gedeclareerd daar ze in de subklassen ook moetkunnen gebruikt worden (of private met voldoende accessors/mutators).

Oefening 10.37 Deze oefening is vrij gelijkaardig aan oefening 10.36; wi-jzigingen:

• klasse Animal

– methode incrementAge verplaatst

Page 128: Oplossingen Methodiek van de Informatica

HOOFDSTUK 10. TECHNIEKEN VOOR VERDERE ABSTRACTIE 121

– abstracte methode getMaxAge gezet

• klasse Fox

– concrete methode getMaxAge

• klasse Rabbit

– concrete methode getMaxAge

Oefening 10.38 Opnieuw vrij gelijkaardig; accessors voorzien voor attributenMAX LITTER SIZE en BREEDING PROBABILITY.

Oefening 10.39 Ik heb gebruik gemaakt van de modifier protected hoewelhet ook mogelijk zou zijn geweest (en waarschijnlijk ook beter) om met privatemodifiers te werken en accessor/mutator methodes te voorzien.

Oefening 10.40 Door gebruik te maken van de protected modifier was hetinderdaad mogelijk om gemakkelijk om een aantal methodes uit een subklassete halen en in een superklasse te zetten (en abstract te declareren).

Oefening 10.36-10.40 Hier volgt de volledige source code voor de klassenAnimal, Fox en Rabbit voor de laatste 4 oefeningen

Listing 10.3: klasse Animalimport java . u t i l . L i s t ;import java . u t i l .Random ;

/∗∗∗ Animal i s an abs t r a c t s up e r c l a s s f o r animals .∗ I t prov ide s f e a t u r e s common to a l l animals ,∗ such as the l o c a t i o n and age .∗∗ @author David J . Barnes and Michael Ko l l ing∗ @version 2006 .03 .30∗/

pub l i c ab s t r a c t c l a s s Animal extends Actor{

// The animal ’ s age .p r i va t e i n t age ;// Whether the animal i s a l i v e or not .p r i va t e boolean a l i v e ;// The animal ’ s p o s i t i o np r i va t e Locat ion l o c a t i o n ;// A shared random number generato r to c on t r o l

breed ing .p r i va t e s t a t i c f i n a l Random rand = new Random( ) ;

/∗∗∗ Create a new animal with age zero ( a new born ) .

Page 129: Oplossingen Methodiek van de Informatica

HOOFDSTUK 10. TECHNIEKEN VOOR VERDERE ABSTRACTIE 122

∗/pub l i c Animal ( ){

age = 0 ;a l i v e = true ;

}

/∗∗∗ Make t h i s animal act − that i s : make i t do

whatever∗ i t wants/needs to do .∗ @param cur r en tF i e l d The f i e l d cu r r en t l y occupied .∗ @param updatedFie ld The f i e l d to t r a n s f e r to .∗ @param newAnimals A l i s t to add newly born animals

to .∗/

abs t r a c t pub l i c void act ( F i e ld cur rentF i e ld ,F i e ld updatedField , L i s t<

Animal> newAnimals ) ;

/∗∗∗ Check whether the animal i s a l i v e or not .∗ @return True i f the animal i s s t i l l a l i v e .∗/

pub l i c boolean i sA l i v e ( ){

re turn a l i v e ;}

/∗∗∗ Te l l the animal that i t ’ s dead now : (∗/

pub l i c void setDead ( ){

a l i v e = f a l s e ;}

/∗∗∗ Return the animal ’ s age .∗ @return The animal ’ s age .∗/

pub l i c i n t getAge ( ){

re turn age ;}

/∗∗∗ Set the animal ’ s age .∗ @param age The animal ’ s age .∗/

Page 130: Oplossingen Methodiek van de Informatica

HOOFDSTUK 10. TECHNIEKEN VOOR VERDERE ABSTRACTIE 123

pub l i c void setAge ( i n t age ){

t h i s . age = age ;}

/∗∗∗ A animal can breed i f i t has reached the breed ing

age .∗/

protec ted boolean canBreed ( ){

re turn age >= getBreedingAge ( ) ;}

/∗∗∗ Return the age at which an animal can s t a r t to

reproduce∗ @return i n t BREEDING AGE The age o f breed ing∗/

pub l i c ab s t r a c t i n t getBreedingAge ( ) ;

/∗∗∗ Return the animal ’ s l o c a t i o n .∗ @return The animal ’ s l o c a t i o n .∗/

pub l i c Locat ion getLocat ion ( ){

re turn l o c a t i o n ;}

/∗∗∗ Set the animal ’ s l o c a t i o n .∗ @param row The v e r t i c a l coo rd inate o f the l o c a t i o n

.∗ @param co l The ho r i z on t a l coo rd inate o f the

l o c a t i o n .∗/

pub l i c void s e tLocat i on ( i n t row , i n t c o l ){

t h i s . l o c a t i o n = new Locat ion ( row , c o l ) ;}

/∗∗∗ Set the animal ’ s l o c a t i o n .∗ @param l o c a t i o n The animal ’ s l o c a t i o n .∗/

pub l i c void s e tLocat i on ( Locat ion l o c a t i o n ){

t h i s . l o c a t i o n = l o c a t i o n ;}

Page 131: Oplossingen Methodiek van de Informatica

HOOFDSTUK 10. TECHNIEKEN VOOR VERDERE ABSTRACTIE 124

/∗∗∗ I n c r e a s e the age .∗ This could r e s u l t in the animal ’ s death .∗/

protec ted void incrementAge ( ){

setAge ( getAge ( ) + 1) ;i f ( age > getMaxAge ( ) ) {

setDead ( ) ;}

}

/∗∗∗ Return the maximum age o f the animal∗ @return i n t MAXAGE The maximum age o f the animal∗/

pub l i c ab s t r a c t i n t getMaxAge ( ) ;

/∗∗∗ Generate a number r ep r e s en t i ng the number o f

b i r ths ,∗ i f i t can breed .∗ @return The number o f b i r t h s (may be zero ) .∗/

protec ted i n t breed ( ){

i n t b i r t h s = 0 ;i f ( canBreed ( ) && rand . nextDouble ( ) <=

getMaximumLitterSize ( ) ) {b i r t h s = rand . next Int ( getMaximumLitterSize ( ) )

+ 1 ;}re turn b i r t h s ;

}

/∗∗∗ Return the breed ing probab l i t y∗ @return i n t BREEDING PROBABILITY The breed ing

p r obab i l i t y∗/

pub l i c ab s t r a c t double getBreed ingProbab l i ty ( ) ;

/∗∗∗ Return the maximum l i t t e r s i z e∗ @return i n t MAX LITTER SIZE The maximum l i t t e r

s i z e∗/

pub l i c ab s t r a c t i n t getMaximumLitterSize ( ) ;

Page 132: Oplossingen Methodiek van de Informatica

HOOFDSTUK 10. TECHNIEKEN VOOR VERDERE ABSTRACTIE 125

}

Listing 10.4: klasse Foximport java . u t i l . L i s t ;import java . u t i l . I t e r a t o r ;import java . u t i l .Random ;

/∗∗∗ A simple model o f a fox .∗ Foxes age , move , eat rabb i t s , and d i e .∗∗ @author David J . Barnes and Michael Ko l l ing∗ @version 2006 .03 .30∗/

pub l i c c l a s s Fox extends Animal{

// Cha r a c t e r i s t i c s shared by a l l f ox e s ( s t a t i c f i e l d s) .

// The age at which a fox can s t a r t to breed .p r i va t e s t a t i c f i n a l i n t BREEDING AGE = 10 ;// The age to which a fox can l i v e .p r i va t e s t a t i c f i n a l i n t MAXAGE = 150 ;// The l i k e l i h o o d o f a fox breed ing .p r i va t e s t a t i c f i n a l double BREEDING PROBABILITY =

0 . 0 9 ;// The maximum number o f b i r t h s .p r i va t e s t a t i c f i n a l i n t MAX LITTER SIZE = 3 ;// The food value o f a s i n g l e rabb i t . In e f f e c t , t h i s

i s the// number o f s t ep s a fox can go be f o r e i t has to eat

again .p r i va t e s t a t i c f i n a l i n t RABBIT FOOD VALUE = 4 ;// A shared random number generato r to c on t r o l

breed ing .p r i va t e s t a t i c f i n a l Random rand = new Random( ) ;

// Ind i v i dua l c h a r a c t e r i s t i c s ( i n s t anc e f i e l d s ) .

// The fox ’ s food l e v e l , which i s i n c r e a s ed by ea t ingr abb i t s .

p r i va t e i n t foodLeve l ;

/∗∗∗ Create a fox . A fox can be c rea ted as a new born (

age zero∗ and not hungry ) or with random age .∗ @param randomAge I f true , the fox w i l l have random

age and hunger l e v e l .∗/

Page 133: Oplossingen Methodiek van de Informatica

HOOFDSTUK 10. TECHNIEKEN VOOR VERDERE ABSTRACTIE 126

pub l i c Fox( boolean randomAge ){

super ( ) ;i f ( randomAge ) {

setAge ( rand . next Int (MAXAGE) ) ;foodLeve l = rand . next Int (RABBIT FOOD VALUE) ;

}e l s e {

// l eave age at 0foodLeve l = RABBIT FOOD VALUE;

}}

/∗∗∗ This i s what the fox does most o f the time : i t

hunts f o r∗ r abb i t s . In the process , i t might breed , d i e o f

hunger ,∗ or d i e o f o ld age .∗ @param cur r en tF i e l d The f i e l d cu r r en t l y occupied .∗ @param updatedFie ld The f i e l d to t r a n s f e r to .∗ @param newAnimals A l i s t to add newly born f oxe s

to .∗/

pub l i c void act ( F i e ld cur rentF i e ld , F i e ldupdatedField , L i s t<Animal> newAnimals )

{incrementAge ( ) ;incrementHunger ( ) ;i f ( i sA l i v e ( ) ) {

// New foxe s are born in to adjacent l o c a t i o n s.

i n t b i r t h s = breed ( ) ;f o r ( i n t b = 0 ; b < b i r t h s ; b++) {

Fox newFox = new Fox( f a l s e ) ;newAnimals . add (newFox) ;newFox . s e tLoca t i on (

updatedFie ld .randomAdjacentLocation (getLocat ion ( ) ) ) ;

updatedFie ld . p lace (newFox) ;}// Move towards the source o f food i f found .Locat ion newLocation = findFood ( cur r entF i e ld ,

getLocat ion ( ) ) ;i f ( newLocation == nu l l ) { // no food found −

move randomlynewLocation = updatedFie ld .

f r e eAdjacentLocat ion ( getLocat ion ( ) ) ;}

Page 134: Oplossingen Methodiek van de Informatica

HOOFDSTUK 10. TECHNIEKEN VOOR VERDERE ABSTRACTIE 127

i f ( newLocation != nu l l ) {s e tLoca t i on ( newLocation ) ;updatedFie ld . p lace ( t h i s ) ; // s e t s

l o c a t i o n}e l s e {

// can ne i t h e r move nor stay −overcrowding − a l l l o c a t i o n s taken

setDead ( ) ;}

}}

/∗∗∗ Make t h i s fox more hungry . This could r e s u l t in

the fox ’ s death .∗/

p r i va t e void incrementHunger ( ){

foodLevel−−;i f ( foodLeve l <= 0) {

setDead ( ) ;}

}

/∗∗∗ Te l l the fox to look f o r r abb i t s ad jacent to i t s

cur rent l o c a t i o n .∗ Only the f i r s t l i v e rabb i t i s eaten .∗ @param f i e l d The f i e l d in which i t must look .∗ @param l o c a t i o n Where in the f i e l d i t i s l o ca t ed .∗ @return Where food was found , or nu l l i f i t wasn ’ t

.∗/

p r i va t e Locat ion findFood ( F i e ld f i e l d , Locat ionl o c a t i o n )

{I t e r a t o r <Location> ad jacentLocat ions =

f i e l d . ad jacentLocat ions (l o c a t i o n ) ;

whi l e ( ad jacentLocat i ons . hasNext ( ) ) {Locat ion where = adjacentLocat i ons . next ( ) ;Animal animal = f i e l d . getAnimalAt ( where ) ;i f ( animal i n s t an c e o f Rabbit ) {

Rabbit rabb i t = ( Rabbit ) animal ;i f ( r abb i t . i sA l i v e ( ) ) {

rabb i t . setDead ( ) ;foodLeve l = RABBIT FOOD VALUE;re turn where ;

}

Page 135: Oplossingen Methodiek van de Informatica

HOOFDSTUK 10. TECHNIEKEN VOOR VERDERE ABSTRACTIE 128

}}re turn nu l l ;

}

/∗∗∗ Generate a number r ep r e s en t i ng the number o f

b i r ths ,∗ i f i t can breed .∗ @return The number o f b i r t h s (may be zero ) .∗/

/∗∗∗ @return A s t r i n g r ep r e s en t a t i on o f the fox .∗/

pub l i c S t r ing toS t r i ng ( ){

re turn ”Fox , age ” + getAge ( ) ;}

/∗∗∗ Return the age at which a Fox can s t a r t to

reproduce∗ @return i n t BREEDING AGE The age o f breed ing∗/

pub l i c i n t getBreedingAge ( ){

re turn BREEDING AGE;}

/∗∗∗ Return the maximum age o f the fox∗ @return i n t MAXAGE The maximum age o f the fox∗/

pub l i c i n t getMaxAge ( ){

re turn MAXAGE;}

/∗∗∗ Return the breed ing probab l i t y∗ @return i n t BREEDING PROBABILITY The breed ing

p r obab i l i t y∗/

pub l i c double getBreed ingProbab l i ty ( ){

re turn BREEDING PROBABILITY;}

/∗∗

Page 136: Oplossingen Methodiek van de Informatica

HOOFDSTUK 10. TECHNIEKEN VOOR VERDERE ABSTRACTIE 129

∗ Return the maximum l i t t e r s i z e∗ @return i n t MAX LITTER SIZE The maximum l i t t e r

s i z e∗/

pub l i c i n t getMaximumLitterSize ( ){

re turn MAX LITTER SIZE ;}

}

Listing 10.5: klasse Rabbitimport java . u t i l . L i s t ;import java . u t i l .Random ;

/∗∗∗ A simple model o f a rabb i t .∗ Rabbits age , move , breed , and d i e .∗∗ @author David J . Barnes and Michael Ko l l ing∗ @version 2006 .03 .30∗/

pub l i c c l a s s Rabbit extends Animal{

// Cha r a c t e r i s t i c s shared by a l l r abb i t s ( s t a t i cf i e l d s ) .

// The age at which a rabb i t can s t a r t to breed .p r i va t e s t a t i c f i n a l i n t BREEDING AGE = 5 ;// The age to which a rabb i t can l i v e .p r i va t e s t a t i c f i n a l i n t MAXAGE = 50 ;// The l i k e l i h o o d o f a rabb i t breed ing .p r i va t e s t a t i c f i n a l double BREEDING PROBABILITY =

0 . 1 5 ;// The maximum number o f b i r t h s .p r i va t e s t a t i c f i n a l i n t MAX LITTER SIZE = 5 ;// A shared random number generato r to c on t r o l

breed ing .p r i va t e s t a t i c f i n a l Random rand = new Random( ) ;

// Ind i v i dua l c h a r a c t e r i s t i c s ( i n s t anc e f i e l d s ) .

/∗∗∗ Create a new rabb i t . A rabb i t may be crea ted with

age∗ zero ( a new born ) or with a random age .∗∗ @param randomAge I f true , the rabb i t w i l l have a

random age .∗/

pub l i c Rabbit ( boolean randomAge )

Page 137: Oplossingen Methodiek van de Informatica

HOOFDSTUK 10. TECHNIEKEN VOOR VERDERE ABSTRACTIE 130

{super ( ) ;i f ( randomAge ) {

setAge ( rand . next Int (MAXAGE) ) ;}

}

/∗∗∗ This i s what the rabb i t does most o f the time − i t

runs∗ around . Sometimes i t w i l l breed or d i e o f o ld age .∗ @param cur r en tF i e l d The f i e l d cu r r en t l y occupied .∗ @param updatedFie ld The f i e l d to t r a n s f e r to .∗ @param newAnimals A l i s t to add newly born rabb i t s

to .∗/

pub l i c void act ( F i e ld cur rentF i e ld , F i e ldupdatedField , L i s t<Animal> newAnimals )

{incrementAge ( ) ;i f ( i sA l i v e ( ) ) {

i n t b i r t h s = breed ( ) ;f o r ( i n t b = 0 ; b < b i r t h s ; b++) {

Rabbit newRabbit = new Rabbit ( f a l s e ) ;newAnimals . add ( newRabbit ) ;newRabbit . s e tLocat i on (

updatedFie ld .randomAdjacentLocation (getLocat ion ( ) ) ) ;

updatedFie ld . p lace ( newRabbit ) ;}Locat ion newLocation = updatedFie ld .

f r e eAdjacentLocat ion ( getLocat ion ( ) ) ;// Only t r a n s f e r to the updated f i e l d i f

the re was a f r e e l o c a t i o ni f ( newLocation != nu l l ) {

s e tLoca t i on ( newLocation ) ;updatedFie ld . p lace ( t h i s ) ;

}e l s e {

// can ne i t h e r move nor stay −overcrowding − a l l l o c a t i o n s taken

setDead ( ) ;}

}}

/∗∗∗ Return the maximum age o f the rabb i t

Page 138: Oplossingen Methodiek van de Informatica

HOOFDSTUK 10. TECHNIEKEN VOOR VERDERE ABSTRACTIE 131

∗ @return i n t MAXAGE The maximum age o f the rabb i t∗/

pub l i c i n t getMaxAge ( ){

re turn MAXAGE;}

/∗∗∗ Return the breed ing probab l i t y∗ @return i n t BREEDING PROBABILITY The breed ing

p r obab i l i t y∗/

pub l i c double getBreed ingProbab l i ty ( ){

re turn BREEDING PROBABILITY;}

/∗∗∗ Return the maximum l i t t e r s i z e∗ @return i n t MAX LITTER SIZE The maximum l i t t e r

s i z e∗/

pub l i c i n t getMaximumLitterSize ( ){

re turn MAX LITTER SIZE ;}

/∗∗∗ @return A s t r i n g r ep r e s en t a t i on o f the rabb i t .∗/

pub l i c S t r ing toS t r i ng ( ){

re turn ”Rabbit , age ” + getAge ( ) ;}

/∗∗∗ Return the age at which a Rabbit can s t a r t to

reproduce∗ @return i n t BREEDING AGE The age o f breed ing∗/

pub l i c i n t getBreedingAge ( ){

re turn BREEDING AGE;}

}

Page 139: Oplossingen Methodiek van de Informatica

Deel II

Oefeningen uit deoefenzittingen

132

Page 140: Oplossingen Methodiek van de Informatica

Hoofdstuk 11

Oefenzitting 30-03

11.1 Tests schrijven

Deze oefeningen zijn gebaseerd op de klassen in het handboek [3] hoofdstuk6, meer bepaald de klassen Appointment en Day op blz. 168 en verder. Debedoeling was voor ieder van de klassen een testklasse te schrijven.Opmerkingen van de assistent:

• Je zal objecten moeten aanmaken

• Lees de commentaar bij de methodes

11.1.1 Eerste testklasse

/∗∗∗ The t e s t c l a s s TestAppointment .∗∗ @author Mart i jn Hemeryck∗ @version 0 .1 2006−03−30∗/

pub l i c c l a s s TestAppointment extends j un i t . framework .TestCase

{Appointment appointment ;

/∗∗∗ Defau l t con s t ruc to r f o r t e s t c l a s s TestAppointment∗/

pub l i c TestAppointment ( ){}

/∗∗∗ Sets up the t e s t f i x t u r e .∗∗ Cal led be f o r e every t e s t case method .

133

Page 141: Oplossingen Methodiek van de Informatica

HOOFDSTUK 11. OEFENZITTING 30-03 134

∗/protec ted void setUp ( ){

appointment = new Appointment ( ”Tandarts ” , 1) ;}

/∗∗∗ Tears down the t e s t f i x t u r e .∗∗ Cal led a f t e r every t e s t case method .∗/

protec ted void tearDown ( ){}

/∗∗∗ Methode om getDurat ion methode van k l a s s e∗ Appointment u i t te t e s t en∗/

pub l i c void testGetDurat ion ( ){

a s s e r tEqua l s (1 , appointment . getDurat ion ( ) ) ;

a s s e r tEqua l s (8 , appointment . getDurat ion ( ) ) ;}

/∗∗∗ Methode om ge tDe s c r i p t i on methode van k l a s s e∗ Appointment u i t te t e s t en∗/

pub l i c void t e s tGetDes c r ip t i on ( ){

a s s e r tEqua l s ( ”Tandarts ” , appointment .g e tDe s c r i p t i on ( ) ) ;

}}

11.1.2 Tweede testklasse

/∗∗∗ The t e s t c l a s s TestDay .∗∗ @author Mart i jn Hemeryck∗ @version 0 .1 2006−03−30∗/

pub l i c c l a s s TestDay extends j un i t . framework . TestCase{

Day day ;Appointment appointment ;

Page 142: Oplossingen Methodiek van de Informatica

HOOFDSTUK 11. OEFENZITTING 30-03 135

/∗∗∗ Defau l t con s t ruc to r f o r t e s t c l a s s TestDay∗/

pub l i c TestDay ( ){}

/∗∗∗ Sets up the t e s t f i x t u r e .∗∗ Cal led be f o r e every t e s t case method .∗/

protec ted void setUp ( ){

day = new Day(1) ;

appointment = new Appointment ( ”Restaurant ” , 1) ;}

/∗∗∗ Tears down the t e s t f i x t u r e .∗∗ Cal led a f t e r every t e s t case method .∗/

protec ted void tearDown ( ){}

/∗∗∗ Methode om getDayNumber methode van k l a s s e∗ Day u i t te t e s t en∗/

pub l i c void testGetDayNumber ( ){

a s s e r tEqua l s (1 , day . getDayNumber ( ) ) ;}

/∗∗∗ Methode om makeAppointment methode van k l a s s e∗ Day u i t te t e s t en∗/

pub l i c void testMakeAppointment ( ){

// p o s i t i e v e t e s ta s s e r tEqua l s ( true , day . makeAppointment (9 ,

appointment ) ) ;

// negat i eve t e s ta s s e r tEqua l s ( f a l s e , day . makeAppointment (9 ,

appointment ) ) ;

Page 143: Oplossingen Methodiek van de Informatica

HOOFDSTUK 11. OEFENZITTING 30-03 136

}

/∗∗∗ Methode om getAppointment methode van k l a s s e∗ Day u i t te t e s t en∗/

pub l i c void testGetAppointment ( ){

day . makeAppointment (9 , appointment ) ;

// p o s i t i e v e t e s ta s s e r tEqua l s ( appointment , day . getAppointment (9 ) ) ;

// negat i eve t e s ta s s e r tEqua l s ( nu l l , day . getAppointment (10) ) ;

}}

11.2 Correctheidsbewijzen

11.2.1 Machtsverheffing

Methode voor een getal x tot een macht n te verheffen. Gebaseerd op slides uitde hoorcolleges.

pub l i c s t a t i c i n t macht ( i n t x , i n t n){

i n t k = 0 , p = 1 ;

whi l e ( k != n){

k = k++;p = x∗p ;}

re turn p ;}

Page 144: Oplossingen Methodiek van de Informatica

Hoofdstuk 12

Oefenzitting 20-04

12.1 Correctheidsbewijzen

Oefeningen uit de bundel. In deel 14 worden nog dergelijke oefeningen verderuitgewerkt.

Listing 12.1: stramien correctheidsbewijs// Algemeen stramien co r r e c th e i d sb ew i j z en

{//Pre< i n i t i a l i s a t i e >// Invwhi l e ( ! stop ){

// Inv AND !STOP. . .// Inv

}

// Post : Inv AND STOP}

Oefening 1 Macht berekenen

Listing 12.2: correctheidsbewijs bij macht

/∗∗∗ Cor r e c the id sbew i j s b i j machtberekeningmethode∗∗ @author Mart i jn Hemeryck∗ @version 0 .1 2006−04−20∗/

137

Page 145: Oplossingen Methodiek van de Informatica

HOOFDSTUK 12. OEFENZITTING 20-04 138

pub l i c c l a s s Macht{

/∗∗∗ Methode om de macht van een g e t a l te berekenen∗/

pub l i c i n t macht ( i n t n){

//PRECONDITIE: n>0 ( anders one ind ige l u s )i n t r e s u l t a a t = 1 ;i n t t e l l e r = 0 ;

//INVARIANT: nˆ0=1 ( t r i v i a a l )// r e s u l t a a t = nwhi le ( t e l l e r != n){

//INVARIANTr e s u l t a a t = r e s u l t a a t ∗n ;

t e l l e r ++;// r e s u l t a a t = nˆ t e l l e r

}//POST: r e s u l t a a t = nˆ t e l l e r AND t e l l e r = 1//POSTCONDITIE: r e s u l t a a t = nˆn

return r e s u l t a a t ;}

}

Oefening 2 Grootste gemene deler

Listing 12.3: correctheidsbewijs bij grootste gemene deler

/∗∗∗ Cor r e c the id sbew i j s voor g r oo t s t e gemene d e l e r∗∗ @author Mart i jn Hemeryck∗ @version 2006−04−20∗/

pub l i c c l a s s GGD{

/∗∗∗ Methode om groo t s t e gemene d e l e r van 2

g e t a l l e n te vinden∗/

pub l i c i n t GGD( in t x , i n t y ){

//PRE x>0, y>0i n t a = x ;

Page 146: Oplossingen Methodiek van de Informatica

HOOFDSTUK 12. OEFENZITTING 20-04 139

i n t b = y ;i n t ggd ;//INVARIANT: ggd (x , y ) = ggd (a , b)whi l e ( a!=b){

//ggd (x , y ) = ggd (a , b) AND a!=b// x>0, y>0, x>y dus x−y >0i f ( a>b) //ggd (x , y ) = ggd (a , b) AND (a > b){

a = a−b ;//ggd (x , y ) = ggd ( a+b , b) = ggd (a , b)

}e l s e// x>0, y>0, x<y dus x−y >0{

b = b−a ;//ggd (x , y ) = ggd (a , b+a ) = ggd (a , b)

}}ggd = a ;//ggd = ggd (x , y ) = ggd (a , b) = a = b//POST ggd = ggd (x , y )

re turn ggd ;}

}

Oefening 3 Bubblesort

Listing 12.4: correctheidsbewijs bij bubblesort

/∗∗∗ Cor r e c the id sbew i j s bubb le sor t∗∗ Zeker op examen !∗ Overgenomen van s l i d e s a s s i s e n t∗∗ @author Mart i jn Hemeryck∗ @version 0 .1 2006−04−20∗/

pub l i c c l a s s BubbleSort{

/∗∗∗ Methode bubb le sor t∗/

pub l i c i n t [ ] bubbleSort ( i n t [ ] r ){

i n t i = r . l ength ;

Page 147: Oplossingen Methodiek van de Informatica

HOOFDSTUK 12. OEFENZITTING 20-04 140

//BUITENSTE INVARIANT: r [ i , . . . , SIZE−1] i sg e s o r t e e rd van

// k l e i n naar groot AND voor a l l e k tussen 0en i −1:

// r [ k ] <=r [ i ]//Gegeven i = r . l ength i s de t r i v i a a l waarwhi l e ( i != 0){

i n t j = 0 ;//BINNENSTE INVARIANT: r [ j ] i s het

g r oo t s t e element van de r i j r [ 0 , . . . , j ]//Gegeven j = 0 i s d i t t r i v i a a l waarwhi l e ( j != i −1){

i f ( r [ j +1] < r [ j ] ){

i n t temp = r [ j +1] ;r [ j +1] = r [ j ] ;r [ j ] = temp ;

}// r i j [ j ] i s het g r oo t s t e element van

de r i j r [ 0 , . . . , j ] AND// r [ j +1] >= r [ j ]//=>// r [ j +1] i s het g r oo t s t e element van

de r i j r [ 0 , . . . , j +1]j++;//BINNENSTE INVARIANT: r [ j ] i s het

g r oo t s t e element van de r i j r [O . . j ]}//BINNENSTE POSTCONDITIE: r [ j ] i s het

g r oo t s t e element van de r i j r [ 0 , . . . , j] AND j = i−1

//=>//BINNENSTE POSTCONDITIE: r [ i −1] i s het

g r oo t s t e element van de r i j r [ 0 , . . , i−1]

//=>// r [ i , . . . , r . length −1] i s g e s o r t e e rd van

k l e i n naar groot//AND voor a l l e k tussen 0 en i−1 ge ld t

r [ k ] <= r [ i ]//AND r [ i −1] i s het g r oo t s t e element van

de r i j r [ 0 , . . . , i −1]//=>// r [ i − 1 , . . . , r . l ength ] i s g e s o r t e e rd van

k l e i n naar groot//AND voor a l l e k tussen 0 en i−1 ge ld t :

r [ k ] <= r [ i ]i−−;

Page 148: Oplossingen Methodiek van de Informatica

HOOFDSTUK 12. OEFENZITTING 20-04 141

//BUITENSTE INVARIANT: r [ i , . . . , r . length−1] i s g e s o r t e e rd van k l e i n naargroot

//AND voor a l l e k tussen 0 en i−1 ge ld t :r [ k ] <= r [ i ]

}//BUITENSTE POSTCONDITIE: r [ i , . . . , r . length

−1] i s g e s o r t e e rd van k l e i n naar groot//AND voor a l l e k tussen 0 en i−1 ge ld t : r [

k ] <= r [ i ] AND i=O//BUITENSTE POSTCONDITIE: r [ 0 , . . . , r . length

−1] i s g e s o r t e e rd van k l e i n naar grootre turn r ;

}}

12.2 Complexiteitsanalyse

Oefening 5 Slechtste geval complexiteit: hele rij afgaan: O(n)

Oefening 6 O(n) + O(log(n)) = O(n)

Oefening 7 Opmerkingen bij deze oefening1:

• de array die wordt teruggegeven, n, moet als lengte r.length+1 hebben;de methode voegInGesorteerdeRij geeft nl. een array terug met als lengtede lengte van de array die werd ingegeven+1 (uit opgave)

• de test voor het while-statement is het best while( i<r.length) (hoewel datin principe niet zo veel mag uitmaken)

• Het sorteren gebeurt automatisch aangezien bij het doorlopen van de lusiedere keer de methode voegGesorteerdeRij wordt opgeroepen; in de op-gave staat dat deze methode de rij die ze binnenkrijgt gesorteerd teruggeeft,met daarbij ook nog de andere parameter die werd meegegeven.

Listing 12.5: sorteeralgoritme en complexiteit

/∗∗∗ Oefening 7∗∗ @author Mart i jn Hemeryck∗ @version 0 .2 2006−06−05∗/

pub l i c c l a s s GesorteerdeRi j en{

/∗∗1Met dank aan een zekere Joris voor het opmerken van een fout in deze oefening

Page 149: Oplossingen Methodiek van de Informatica

HOOFDSTUK 12. OEFENZITTING 20-04 142

∗ Sor t e e r de r i j e n door gebru ik te maken van eenmethode voegInGesortee rdeRi j

∗/pub l i c i n t [ ] s o r t e e rR i j ( i n t [ ] r ){

i n t i = 0 ;i n t [ ] n = in t n [ r . l ength +1] ;

whi l e ( i < r . l ength ){

n = voegInGesor tee rderRi j (n , r [ i ] ) ;i++;

}

re turn n ;}

}

Page 150: Oplossingen Methodiek van de Informatica

Hoofdstuk 13

Oefenzitting 27-04

In deze oefenzitting behandelden we oefeningen uit hoofdstuk 8 en 9.

13.1 Extra oefeningen bij hoofdstuk 8

Oefening 8.10 1

Opgave Implementeer de klassen Rechthoek en Vierkant. Implementeer 2versies van de klasse Rechthoek:

• een die methodes declareert waarmee je de dimensies van de rechthoekkunt wijzigen

• een waar je dit niet kunt

Is de overervingsstructuur dezelfde?

Oplossing

• Dimensies wijzigen niet mogelijk

Listing 13.1: klasse Rechthoek

/∗∗∗ Write a d e s c r i p t i o n o f c l a s s Rechthoek here .∗∗ @author Mart i jn Hemeryck∗ @version 0 .1 2006−04−27∗/

pub l i c c l a s s Rechthoek{

pr i va t e i n t ba s i s ;p r i va t e i n t he ight ;

/∗∗1Deze oefening is een uitbreiding van oefening 8.10 (blz. 102).

143

Page 151: Oplossingen Methodiek van de Informatica

HOOFDSTUK 13. OEFENZITTING 27-04 144

∗ Constructor f o r ob j e c t s o f c l a s s Rechthoek∗/

pub l i c Rechthoek ( i n t bas i s , i n t he ight ){

t h i s . b a s i s = ba s i s ;t h i s . he ight = he ight ;

}

}

• Dimensies wijzigen mogelijkWe voegen een aantal set−methodes toe.

De overervingstructuur is dus niet dezelfde voor de 2.

Page 152: Oplossingen Methodiek van de Informatica

Deel III

Uitwerking andereoefeningen en examens

145

Page 153: Oplossingen Methodiek van de Informatica

Hoofdstuk 14

Oefeningen op algoritmes

Voor de opgave, zie deel A, voor de oefeningen zoals gezien in de oefenzitting,zie deel 12.

14.1 Correctheidsbewijzen

Oefening 1 Bewijzen van algoritme dat nn berekent, met n een natuurlijkgetal.

// Pre cond i t i e : n > 0i n t r e s u l t a a t = 1 ;i n t t e l l e r = 0 ;

// Invar i an t : resultaat = nteller

whi le ( t e l l e r !=n){

// Invar i an t : resultaat = nteller

r e s u l t a a t = r e s u l t a a t ∗ n ;// Invar i an t : resultaat = nteller+1

t e l l e r ++;// Invar i an t : resultaat = nteller

}// Pos t cond i t i e :// resultaat = nteller

// AND// t e l l e r = n ;// Eindighe id : t e l l e r s t a r t op 0 en wordt met 1 verhoogd

in e l k e stap ,// om u i t e i n d e l i j k n te bere iken , d i e c f r . p r e c ond i t i e

minstens g r o t e r// dan 1 i s .

Oefening 2 Grootste gemene deler van twee natuurlijk getallen. Versie oefen-zitting: zie deel 12.1.

146

Page 154: Oplossingen Methodiek van de Informatica

HOOFDSTUK 14. OEFENINGEN OP ALGORITMES 147

/∗ Bereken de g r oo t s t e gemene d e l e r van twee na t uu r l i j k eg e t a l l e n

∗ @param in t x , y∗ @return i n t ggd : de g r oo t s t e gemene d e l e r∗/

pub l i c i n t ggd ( i n t x , i n t y ){// Pre cond i t i e : x > 0, y > 0

i n t a = x ;i n t b = y ;i n t ggd ;

// Invar i an t : ggd (x , y ) = ggd (a , b)whi l e ( a!=b){

// Invar i an t : ggd (x , y ) = ggd (a , b)// x > 0, y > 0, x > y ⇒ x− y > 0i f ( a>b){

// ggd (x , y ) = ggd (a , b)a = a−b ;// ggd (x , y ) = ggd ( a+b , b) = ggd (a , b)

}e l s e// x > 0, y > 0, x < y ⇒ x− y > 0{

//ggd (x , y ) = ggd (a , b)b = b−a ;// ggd (x , y ) = ggd (a , a+b) = ggd (a , b)

}}ggd = a ;

// Pos t cond i t i e :// ggd (x , y ) = ggd (a , b)// AND// a = b

return ggd ;}

Listing 14.1: correctheidsbewijs bij bubbleSort

/∗∗∗ Cor r e c the id sbew i j s bubb le sor t∗∗ Zeker op examen !∗ Overgenomen van s l i d e s a s s i s e n t

Page 155: Oplossingen Methodiek van de Informatica

HOOFDSTUK 14. OEFENINGEN OP ALGORITMES 148

∗∗ @author Mart i jn Hemeryck∗ @version 0 .1 2006−04−20∗/

pub l i c c l a s s BubbleSort{

/∗∗∗ Methode bubb le sor t∗/

pub l i c i n t [ ] bubbleSort ( i n t [ ] r ){

i n t i = r . l ength ;//BUITENSTE INVARIANT: r [ i , . . . , SIZE−1] i s

g e s o r t e e rd van// k l e i n naar groot AND voor a l l e k tussen 0

en i −1:// r [ k ] <=r [ i ]//Gegeven i = r . l ength i s de t r i v i a a l waarwhi l e ( i != 0){

i n t j = 0 ;//BINNENSTE INVARIANT: r [ j ] i s het

g r oo t s t e element van de r i j r [ 0 , . . . , j ]//Gegeven j = 0 i s d i t t r i v i a a l waarwhi l e ( j != i −1){

i f ( r [ j +1] < r [ j ] ){

i n t temp = r [ j +1] ;r [ j +1] = r [ j ] ;r [ j ] = temp ;

}// r i j [ j ] i s het g r oo t s t e element van

de r i j r [ 0 , . . . , j ] AND// r [ j +1] >= r [ j ]//=>// r [ j +1] i s het g r oo t s t e element van

de r i j r [ 0 , . . . , j +1]j++;//BINNENSTE INVARIANT: r [ j ] i s het

g r oo t s t e element van de r i j r [O . . j ]}//BINNENSTE POSTCONDITIE: r [ j ] i s het

g r oo t s t e element van de r i j r [ 0 , . . . , j] AND j = i−1

//=>//BINNENSTE POSTCONDITIE: r [ i −1] i s het

g r oo t s t e element van de r i j r [ 0 , . . , i−1]

//=>

Page 156: Oplossingen Methodiek van de Informatica

HOOFDSTUK 14. OEFENINGEN OP ALGORITMES 149

// r [ i , . . . , r . length −1] i s g e s o r t e e rd vank l e i n naar groot

//AND voor a l l e k tussen 0 en i−1 ge ld tr [ k ] <= r [ i ]

//AND r [ i −1] i s het g r oo t s t e element vande r i j r [ 0 , . . . , i −1]

//=>// r [ i − 1 , . . . , r . l ength ] i s g e s o r t e e rd van

k l e i n naar groot//AND voor a l l e k tussen 0 en i−1 ge ld t :

r [ k ] <= r [ i ]i−−;//BUITENSTE INVARIANT: r [ i , . . . , r . length

−1] i s g e s o r t e e rd van k l e i n naargroot

//AND voor a l l e k tussen 0 en i−1 ge ld t :r [ k ] <= r [ i ]

}//BUITENSTE POSTCONDITIE: r [ i , . . . , r . length

−1] i s g e s o r t e e rd van k l e i n naar groot//AND voor a l l e k tussen 0 en i−1 ge ld t : r [

k ] <= r [ i ] AND i=O//BUITENSTE POSTCONDITIE: r [ 0 , . . . , r . length

−1] i s g e s o r t e e rd van k l e i n naar grootre turn r ;

}}

Een andere manier om het bubbleSort algoritme uit te werken is om als volgtte werken [4]. Het bewijs hiervan wordt hier niet gegeven.

/∗ bubbleSort−a lgor i tme , v e r s i e handboek 2004−2005∗∗ @param in t [ ] number : onge so r t e e rd∗/

pub l i c void bubbleSort ( i n t [ ] number ){

i n t temp ;i n t bottom ;boolean exchanged = true ;

bottom = number . length −2;

whi l e ( exchanged ){

exchanged = f a l s e ;

f o r ( i n t i = 0 ; i <= bottom ; i++){

i f ( number [ i ] > number [ i +1])

Page 157: Oplossingen Methodiek van de Informatica

HOOFDSTUK 14. OEFENINGEN OP ALGORITMES 150

{temp = number [ i ] ;number [ i ] = number [ i +1] ;number [ i +1] = temp ;

exchanged = true ;}

}bottom−−;}

}

Oefening 4 Bedenk een programma dat de faculteit van een getal n berekent.

• vereiste preconditiesn ∈ N

• gewenste postconditiesfac = (i− 1)!︸ ︷︷ ︸

invariant

AND i = n + 1︸ ︷︷ ︸!test

• mogelijke invariantfac = (i− 1)!

• oplossingsmethode

/∗ bereken de f a c u l t e i t van een na tuu r l i j k g e t a l n∗ @param in t n∗ @return i n t f a c∗/

pub l i c i n t f a c ( i n t n){

// Pre cond i t i e : n ∈ Ni n t f a c = 1 ;i n t i = 1 ;

// Invar i an t : f a c = ( i −1) !// Tr i v i a a l geva l : 1 = 0 !whi l e ( i != n+1){

// Invar i an t : f a c = ( i −1) !f a c = fac ∗ i ;// Invar i an t : f a c = i !i++;// Invar i an t : f a c = i ! AND i = i+1 ⇒ f a c = (

i −1) !}

re turn f a c ;// Pos t cond i t i e :

Page 158: Oplossingen Methodiek van de Informatica

HOOFDSTUK 14. OEFENINGEN OP ALGORITMES 151

// f a c = ( i −1) !// AND// i = n+1;// Eindighe id : i s t a r t vanaf 1 en verhoogt b i j i e d e r e

i t e r a t i e met 1 .// De lu s e i nd i g t wanneer i = n+1 o f a l s n = i−1 dus

f a c = n !}

14.2 Complexiteit van algoritmes

Oefening 5 Een mogelijke implementatie

/∗ Geef het aanta l nu l l en terug voor een g e s o r t e e rd e r i j∗ @param in t [ ] r i j∗ @return i n t aanta l∗/

pub l i c i n t gee fAanta lNul l en ( i n t [ ] r i j ){

i n t aanta l = 0 ;i n t i = 0 ;

whi l e ( r i j [ i ]=0){

aanta l++;}re turn aanta l ;

}

Complexiteitsanalyse

T = Tinitialisatie + Treturn + n · (Trij[i]=0 + Taantal + +)= a + b + n · (c + d)= O(n)

Oefening 6 Rekenen met grootte-ordes:

T = Tlus maximum zoeken + Ttweede lus

= O(n) + O(log2 n)= O(n)

Listing 14.2: sorteeralgoritme en complexiteit

/∗∗∗ Oefening 7∗

Page 159: Oplossingen Methodiek van de Informatica

HOOFDSTUK 14. OEFENINGEN OP ALGORITMES 152

∗ @author Mart i jn Hemeryck∗ @version 0 .2 2006−06−05∗/

pub l i c c l a s s GesorteerdeRi j en{

/∗∗∗ Sor t e e r de r i j e n door gebru ik te maken van een

methode voegInGesortee rdeRi j∗/

pub l i c i n t [ ] s o r t e e rR i j ( i n t [ ] r ){

i n t i = 0 ;i n t [ ] n = in t n [ r . l ength +1] ;

whi l e ( i < r . l ength ){

n = voegInGesor tee rderRi j (n , r [ i ] ) ;i++;

}

re turn n ;}

}

Oefening 8 Complexiteit heeft enkel betrekking tot het asymptotisch gedrag.Op basis van deze gegevens is het dus niet mogelijk af te leiden welke van de tweealgoritmes de grootste complexiteit heeft. Stel bijvoorbeeld dat algoritme A eencomplexiteit heeft die lineair afhankelijk is van de grootte van de rij (O(n)) enalgoritme B een complexiteit die onafhankelijk is van de grootte van de rij (0(1))- dus altijd 20s uitvoeringstijd - dan heeft algoritme B een lagere complexiteit.

Oefening 9 Aangezien het interval nogal klein is, kan er enkel op basis vandeze gegevens niet besloten worden wat de complexiteit is. Opnieuw, complex-iteit behelst het asymptotisch gedrag.

Oefening 10 Op basis van de grafiek is te zien dat voor het telkens vergelijkenvan twee documenten het voordeliger is van algoritme B te gebruiken (O(n)).In het andere geval, waar er 400 documenten moeten worden vergeleken is hetbeter om het andere algoritme te gebruiken.

Oefening 11.A Algoritme

/∗ Bereken n · a∗ @param in t a , n∗ @return i n t product∗/

pub l i c i n t maal ( i n t a , i n t n)

Page 160: Oplossingen Methodiek van de Informatica

HOOFDSTUK 14. OEFENINGEN OP ALGORITMES 153

Figuur 14.1: Mogelijke complexiteit voor de algoritmes. A: rood (O(n)), B:blauw (O(1))

Page 161: Oplossingen Methodiek van de Informatica

HOOFDSTUK 14. OEFENINGEN OP ALGORITMES 154

{i n t i = 1 ;i n t product = 0 ;

whi l e ( i !=n){

product += a ;i++;

}re turn product ;

}

Complexiteit: O(n)

Oefening 11.B Algoritme

/∗ Bereken n · a∗ @param in t a , n∗ @return i n t product∗/

pub l i c i n t snelMaal ( i n t a , i n t b){

i n t k = b ;i n t y = a ;i n t p = 0 ;

whi l e ( k !=0){

i f ( k%2 == 0){

k = k /2 ;y = y + y ;

}e l s e{

k = k−1;p = y+p ;

}}re turn p ;

}

Page 162: Oplossingen Methodiek van de Informatica

Hoofdstuk 15

Examen augustus 2004

De antwoorden op de vragen van het examen 2004 die hier staan uitgewerkt,komen uit een oefenzitting en zijn samen met een assistent gemaakt. Voor denota’s van die oefenzitting, zie B.

Algemene vragen

Wet van Moore? Rekenkracht neemt exponentieel toe

Array: zowel primitieve als referentietypes? Samen gaat niet.1

Switch commando? ”Cases”doorlopen: zelfde als if - else - if - else - . . .

Verschil while - do-while? do-while wordt altijd minstens een maaldoorgelopen, test staat op het einde.

/∗∗ Recurs i eve methode voor het bepalen van een som∗ @param in t a , b∗ @return i n t r e s u l t a a t∗/

pub l i c s t a t i c i n t som( i n t a , i n t b){

// pre−c ond i t i e : a , b >= 0in t r e s u l t a a t ;

// t r i v i a a l geva li f (b == 0) {r e s u l t a a t = a ;} e l s e {a++;b−−;

1Variant: ”Kan in JAVA een array elementen van verschillende klassen bezitten?”Ja, viaovererving

155

Page 163: Oplossingen Methodiek van de Informatica

HOOFDSTUK 15. EXAMEN AUGUSTUS 2004 156

som(a , b) ;}// r e s u l t a a t = a + breturn r e s u l t a a t ;

}

Constructors

Leg uit hoe constructoren werken en hoe ze uitgevoerd worden bijoproep

• Declaratie: . . .

• Initialisatie: . . .

Best bespreking uit handboek bekijken

Moet elke klasse een constructor bevatten? Constructor hebben isniet noodzakelijk, maar wel nuttig voor het initialiseren van bepaalde param-eters voor een object van een bepaalde klasse. Bij het niet invoegen van eenconstructor wordt de default-constructor opgeroepen; d.i. de constructor van desuperklasse. Aangezien alle objecten subklasse zijn van de Object-klasse hebbenalle objecten dus per definitie een constructor. In de cursus wordt aangeradenaltijd een constructor te voorzien voor alle klassen, ook al is deze leeg.

Geheugentoestand schetsen na uitvoeren stukje code Zie scans

this-constructor this (): kan constructor van binnen zelfde klasse op-nieuw aanroepen. Nuttig om duplicatie van code te vermijden.

Garbage-collection Is het verwijderen van objecten waar geen referentiemeer voor bestaat. Nuttig om het geheugengebruik van een PC efficient te latenverlopen.

Algoritmes schrijven

import java . lang . Math ;

pub l i c s t a t i c i n t aanta lPhytagora sTr ip l e t s ( i n t [ ] x , i n t [ ]y , i n t [ ] z )

{i n t aanta lPhytagora sTr ip l e t s ;i n t t e l l e r = 0 ;

f o r ( i n t i = 0 ; i < x . l ength ; i++){f o r ( i n t j = 0 ; j < y . l ength ; j++){

Page 164: Oplossingen Methodiek van de Informatica

HOOFDSTUK 15. EXAMEN AUGUSTUS 2004 157

f o r ( i n t k = 0 ; k < z . l ength ; k++){

i f ( x [ i ] ∗ x [ i ] + y [ j ] ∗ y [ j ] == z [ k ] ∗ z [ k ] ) {t e l l e r ++;}}

}}re turn t e l l e r ;

}

import java . lang . Math ;

pub l i c s t a t i c i n t aanta lPhytagora sTr ip l e t s ( i n t [ ] x , i n t [ ]y , i n t [ ] z )

{i n t t e l l e r , k , sum = 0 ;boolean next = f a l s e ;

f o r ( i n t i = 0 ; i < x . l ength ; i++){k = 0 ;f o r ( i n t j = 0 ; j < y . l ength && k < z . l ength ; j++)

{sum = x [ i ] ∗ x [ i ] + y [ j ] ∗ y [ j ] ;next = f a l s e ;

do{i f (sum == z [ k ] ∗ z [ k ] ) {t e l l e r ++;k++;}i f (sum < z [ k ] ∗ z [ k ] ) {next = true ;}i f (sum > z [ k ] ∗ z [ k ] ) {k++;}

whi le ( k < z . l ength && ! next ) ;}}

}re turn t e l l e r ;

}

Bespreking stuk JAVA-code

Page 165: Oplossingen Methodiek van de Informatica

HOOFDSTUK 15. EXAMEN AUGUSTUS 2004 158

j = 0 ;f = 0 ;

Invariante relatie 1 voor buitenste lus Postconditie

f =n∑

i=0

i!

dus

f =j−1∑i=0

i!︸ ︷︷ ︸invariant

&& j = n + 1

fac = k ! && k ==j

Eindrelatie 2 voor binnenste lus Postconditie:

f a c = j !

Vraag over inheritance

Beschrijf voordelen van inheritance Opmerking: zie cursus voor meeruitleg

• Code hergebruiken

• Abstracte methodes

• Polymorfisme, dynamische binding

• Makkelijk uitbreidbaar, subklasses zijn makkelijk uitbreidbaar

Page 166: Oplossingen Methodiek van de Informatica

Hoofdstuk 16

Examen juni 2004

Dit examen is alleen opgelost geweest en is bijgevolg niet gecontroleerd geweestdoor een assistent en kan als dusdanig nog wat fouten bevatten. Voor opgavevan de examens: zie Toledo

Algemene vragen

Bytecode machine-afhankelijk? Om een JAVA-programma te schrijvenga je als volgt te werk. De broncode (Eng.: source-code) van het programmawordt in JAVA-syntax geschreven, een taal die leesbaar is voor mensen. Omde broncode voor een computer ’leesbaar’ te maken moet je de JAVA-codecompileren waaruit de Bytecode voorkomt. Deze Bytecode is daarbij machine-onafhankelijk; voor het laten werken van je Bytecode heb je nl. nog een VirtualMachine (VM) nodig wat niets anders is dan een softwarematige ’component’die de burg slaat tussen de Bytecode en het platform waarop je werkt; voor iederplatform bestaat dan ook een aparte Virtual Machine. Conclusie: Bytecode enJAVA-broncode zijn allebei machine-onafhankelijk daar er voor ieder platformeen andere VM bestaat. Vandaar dan ook ”Write once, run everywhere”.

Array met arrays van verschillende lengtes? Een array kan alle soortendata bevatten, zowel primitieve datatypes (int, double, long, . . . ) als referen-tietypes (objecttypes). Aangezien een array zelf ook een datastructuur is kaneen array zelf andere arrays bevatten. Wat de lengte van die arrays is maaktdaarbij niet uit.

Array lengte 10, alle elementen initialiseren? Voor een array is hetniet noodzakelijk om alle elementen van deze array te initialiseren. Elementendie niet geınitialiseerd zijn bevatten waarde null.

Twee versies programma, welke juist? De tweede versie is de juisteaangezien je in het eerste geval voor een snelheid hoger dan 50 altijd dezelfdeboete krijgt, onafhankelijk van of je snelheid hoger dan 70 of dan wel hoger dan90 was.

159

Page 167: Oplossingen Methodiek van de Informatica

HOOFDSTUK 16. EXAMEN JUNI 2004 160

/∗ Bereken het product van twee g e t a l l e n∗ m. b . v . een r e c u r s i e v e methode∗ @param in t a , b ;∗ @return r e s u l t a a t ;∗/

pub l i c s t a t i c i n t product ( i n t a , i n t b){

// Pre cond i t i e : a, b ≥ 0i n t r e s u l t a a t ;

// Tr i v i a a l geva li f (b==1){

r e s u l t a a t = a ;}// Recurs i ee l s e{

a += a ;b−−;product ( a , b) ;

}// Resu l taat = a · bre turn r e s u l t a a t ;

}

Vragen over interne werking JAVA

Call-by-reference werking Voorbeeld: stel dat je beschikt over een lijstvan personen (een array) waarbij je voor ieder van de personen beschikt overeen aantal gegevens zoals geboortedatum, adres, telefoonnr.. . . . (attributen vande personen). Stel nu dat je voor een welbepaald Persoon-object het attribuutadres wilt opvragen, waarbij dit attribuut zelf een objecttype is van het typeAdres. Een methode die dit doet zou er als volgt kunnen uitzien:

/∗∗ Geef van een persoon het adres terug∗ @return Adres adres∗/

pub l i c Adres gee fAdres ( ){

re turn adres ;}

Hierbij is adres een attribuut van de klasse Persoon en van het type Adres.

• oproepIn een ander stuk van het programma (in een andere klasse) staat bijvoor-

Page 168: Oplossingen Methodiek van de Informatica

HOOFDSTUK 16. EXAMEN JUNI 2004 161

beeld volgende aanroep: persoon.geefAdres(). Hierop wordt de meth-ode van het dynamisch type Persoon aangeroepen (in dit geval is hetdynamisch type gelijk aan het statisch type. Er wordt gekeken naar deparameters; deze kunnen zowel van het primitieve type als van het refer-entietype zijn. Het primitieve type kan zonder meer worden meegegeven,voor het referentietype wordt niet het object zelf meegegeven maar deverwijzing die er bestaat naar dat object wordt meegegeven. In dit gevalworden er geen parameters verwacht, dus is dat hier niet zo van belang.

• uitvoerOp het Persoon-object wordt de methode uitgevoerd (d.i., op de verwijzingnaar persoon); het attribuut adres van het type Adres van het objectpersoon wordt opgevraagd. Het attribuut adres is hierbij zelf ook weereen referentie naar een Adres-object.

• terugkeerAls de verwijzing naar adres is opgevraagd wordt deze weer teruggegeven.adres kan op haar beurt ook weer attributen bezitten die gedefinieerd staanin de klasse Adres en deze teruggeven (accessor-methodes) of bewerken(mutator-methodes) door methodes die bestaan in de klasse Adres.

Array: welk soort type van doorgeven? Een array is van het eenobject-type: het heeft een attribuut length en voor ieder van de plaatsen in dearray ofwel een verwijzing naar een object ofwel een primitief data-type.

Primitieve types doorgeven door call-by-reference? Dat is mogelijken daar bestaat zelfs een reeks van bibliotheekklassen voor, de zogenaamdewrapper-klassen. Voor integers bestaat zo bijvoorbeeld de bibliotheekklasseInteger die als attribuut een int heeft. In principe is het best mogelijk zelfeen wrapper-klasse te schrijven; bijvoorbeeld:

/∗∗ Voorbeeld van hoe een wrapper−k l a s s e werkt∗/

pub l i c c l a s s someWrapperClass{

// a t t r i buu ti n t i ;

// con s t ruc to rpub l i c someWrapperClass ( ){}

// tweede cons t ruc to r voor a l s j e z e l f het p r im i t i e ftype w i l t i n i t i a l i s e r e n

pub l i c someWrapperClass ( i n t i ){

t h i s . i = i ;}

Page 169: Oplossingen Methodiek van de Informatica

HOOFDSTUK 16. EXAMEN JUNI 2004 162

// setMethodepub l i c s e tAt t r i b ( i n t i ){

t h i s . i = i ;}

// getMethodepub l i c i n t ge tAtt r ib ( ){

re turn i ;}

}

Je kan op deze manier dus referentie naar objecten van het type someWrapperClassmeegeven en van die objecten via de get-methode (getAttrib in dit geval) het

primitief type opvragen.

Parameters via call-by-value veranderen? Een parameter van hetprimitief datatype kan als formele parameter doorgegeven worden, maar de toe-stand van die formele parameter zal niet veranderen door een methode oproep.Het is mogelijk om deze formele parameter als zijnde een lokale variabele te ge-bruiken binnen de body van een methode en deze daarna ook terug te geven ineen andere toestand, maar de toestand van de formele parameter wordt daarbijniet veranderd.

Voorbeeld:

pub l i c i n t doSomething ( i n t something ){

something += 3 ;

re turn something ;}

Door deze methode vanuit een andere klasse op te roepen verandert somethingzelf niet, tenzij uiteraard het resultaat van deze methode wordt toegekend aande parameter something zelf. Het punt is in ieder geval dat op deze manier deparameter die wordt meegegeven aan deze methode zelf niet verandert.

Wel is natuurlijk mogelijk om in een bepaalde klasse zelf de attributen vaneen klasse - die zowel van het primitieve type als van het referentietype zijn - teveranderen via mutator-methodes (void als returntype).

Implementeren van een methode

Gewone complexiteit Algoritme:

pub l i c s t a t i c i n t aantalKwadraatParen ( i n t [ ] x ){

i n t aanta l = 0 ;

Page 170: Oplossingen Methodiek van de Informatica

HOOFDSTUK 16. EXAMEN JUNI 2004 163

f o r ( i n t i = 0 ; i <= x . l ength ; i++){

f o r ( i n t j = 0 ; j <= x . l ength ; j++){

i f ( x [ i ]∗ x [ i ] == x [ j ] ){

aanta l++;}

}}re turn aanta l ;

}

Complexiteit

T = Tinitialisatie + n · (Teerste lus + n · (Ttweede lus + Taantal++ + Tvergelijken))= a + n · (b + n · (c + d + e))

= O(n2)

Lagere complexiteit: binair algoritme Nu is er gegeven dat de rijgesorteerd is. In zo een geval is het altijd mogelijk om een algoritme met lagerecomplexiteit te schrijven.

pub l i c s t a t i c i n t aantalKwadraatParen ( i n t [ ] x ){

i n t aanta l = 0 ;i n t gezocht ;

f o r ( i n t i =0; i !=x . l ength ; i++){

gezocht = x [ i ]∗ x [ i ] ;

i n t low = 0 ;i n t high = x . length −1;i n t mid ;

whi l e ( low!=high ){

mid = ( low+high ) /2 ;

i f ( gezocht <= x [ mid ] ){

high = mid ;}e l s e{

low = mid + 1 ;}

}

Page 171: Oplossingen Methodiek van de Informatica

HOOFDSTUK 16. EXAMEN JUNI 2004 164

i f ( x [ low ] == gezocht ){

aanta l++;}

}re turn aanta l ;

}

Opmerking: het is waarschijnlijk mogelijk om dit algoritme nog anders teschrijven aangezien er nu geen rekening wordt gehouden met dat altijd geldtdat gezocht > x[ i ].

Complexiteit

T = Tbuitenste lus · Tbinnenste lus

= O(n) ·O(log2 n)= n log2 n

Waarbij er van wordt uitgegaan dat voor het binaire zoeken de complexiteitvan orde O(log2 n) is.

Redeneren over algoritmes Stukje code

// i n t n i s r eeds bepaald door de gebru ike r

i n t k ;i n t f a c ;

// i n i t i a l i s a t i e

k = 0 ;f a c = 1 ;

// i n v a r i a n t i e r e l a t i e : f a c = k !// t r i v i a a l geva l : 1 = 0 !

whi l e ( k!=n){

f a c = fac ∗( k+1) ;// inv : f a c = (k−1) !k++;// inv : f a c = (k−1) ! && k++ ⇒ f a c = k !

}}// e i n d r e l a t i e : f a c = n ! && k = n

Initialisatie k moet gelijk zijn aan 0, fac aan 1

Page 172: Oplossingen Methodiek van de Informatica

HOOFDSTUK 16. EXAMEN JUNI 2004 165

Oneindige lus Als n = 0 zal de lus nooit uitgevoerd worden (k is initieelook 0, dus de test zal van de eerste keer al falen).

Invariante relatie voor de lus fac = k!

Herschrijf code

Programma ontwikkelen Een mogelijk klassediagram:

Figuur 16.1: Mogelijk klassediagram voor oefening 5

Extra veronderstellingen: alle horecazaken liggen op een plein; horeca-zakenliggen niet op straten tussen pleinen in. Implementatie wordt hier ook nietgegeven.

Page 173: Oplossingen Methodiek van de Informatica

Hoofdstuk 17

Examen juni 2003

Dit examen is alleen opgelost geweest en is bijgevolg niet gecontroleerd geweestdoor een assistent en kan als dusdanig nog wat fouten bevatten. Voor opgavevan de examens: zie Toledo

Algemene vragen

Wet van Moore De wet van Moore stelt vast dat de rekenkracht vancomputers exponentieel toeneemt; iedere 18 maanden verdubbelt de rekenkrachtvan een computer.

Bytecode, machine-afhankelijk? Om een JAVA-programma te schri-jven ga je als volgt te werk. De broncode (Eng.: source-code) van het pro-gramma wordt in JAVA-syntax geschreven, een taal die leesbaar is voor mensen.Om de broncode voor een computer ’leesbaar’ te maken moet je de JAVA-codecompileren waaruit de Bytecode voorkomt. Deze Bytecode is daarbij machine-onafhankelijk; voor het laten werken van je Bytecode heb je nl. nog een VirtualMachine (VM) nodig wat niets anders is dan een softwarematige ’component’die de burg slaat tussen de Bytecode en het platform waarop je werkt; voor iederplatform bestaat dan ook een aparte Virtual Machine. Conclusie: Bytecode enJAVA-broncode zijn allebei machine-onafhankelijk daar er voor ieder platformeen andere VM bestaat. Vandaar dan ook ”Write once, run everywhere”.

In JAVA, elementen van array van verschillende klassen? In principeis het zo dat de elementen van een array allemaal hetzelfde statische type moetenhebben. De elementen van een array kunnen echter wel verschillen in hun dy-namisch type, m.a.w. is het mogelijk via overerving om in een array elementenvan verschillende klassen te bevatten, doch behoren deze elementen wel dan toteen bepaalde overervingsstructuur.

Complexiteit en uitvoeringsstijd? Aangezien er asymptotisch gedragmag verondersteld worden, kan er worden uitgegaan van een functioneel verbandtussen de uitvoeringsduur en de lengte van de rij. Als de lengte van de array 3maal zo groot wordt zal, ten gevolge van het O(n2) gedrag, de uitvoeringsduur32 zo lang worden of 9 maal zo lang: 25ms · 9 = 225ms

166

Page 174: Oplossingen Methodiek van de Informatica

HOOFDSTUK 17. EXAMEN JUNI 2003 167

Primitief type in JAVA JAVA heeft twee grote groepen van datatypes,nl. primitieve types en objecttypes of referentietypes. Het primitief type is sim-pele, low-level numerieke data waar de feitelijke berekeningen mee gebeuren.Voorbeelden van primitieve types zijn int, double, long, float , . . . . Daartegen-over staan de objecttypes. Bij het oproepen van een objecttype wordt altijd eenreferentie naar dat object opgeroepen. Een object heeft dan bepaalde attributendie zelf verwijzingen kunnen zijn naar andere objecten of die van het primitievetype zijn.

Bespreek visibility-modifiers

• publicMethodes en attributen die als visibility-modifier public hebben kunnendoor alle andere klassen opgeroepen en gebruikt worden.

– pro: Als je een methode of attribuut public declareert hoef je je geenzorgen te maken of je deze later kan oproepen of niet; je zal dezealtijd kunnen oproepen.

– contra: Het public declareren van attributen/methodes wordt overhet algemeen ten zeerste afgeraden. Bij het ontwikkelen van pro-gramma’s wordt in de OOP-methodologie naar een zo laag mogeli-jke afhankelijkheid tussen de verschillende componenten. Dit wordtgedaan omdat een lagere afhankelijkheid tussen componenten er toeleidt dat een programma beter te onderhouden is - beter uit te brei-den, makkelijker te herbruiken en minder snel te misbruiken.

• privateMethodes en attributen die private gedeclareerd staan kunnen enkel bin-nen een de klasse zelf aangesproken worden.

– pro: Teneinde een zo laag mogelijke afhankelijkheid te hebben tussende verschillende componenten van een programma is het goed zo veelmogelijk attributen en methodes private te declareren.

– contra: Je kan de attributen en methodes van alle klassen niet meervrij aanroepen als ze private gedeclareerd staan. Dit probleem isechter wel op te lossen door het voorzien van zogenaamde accessor-methodes, d.i. methodes met als modifier public die private at-tributen teruggeven.

• protectedDeze modifier is vooral van belang bij de bespreking van overerving: meth-odes en attributen die protected gedeclareerd staan kunnen enkel binnende klasse zelf en door de subklassen (d.i., de klassen die overerven van debeschouwde klasse) aangeroepen worden.

– pro: Net zoals in de bespreking van de private-modifier is het ge-bruik van protected declaraties interessant om een lage mate vanafhankelijkheid tussen klassen te verkrijgen. protected heeft daarbijdan nog het voordeel dat de subklassen bepaalde attributen van desuperklasse kunnen gebruiken.

Page 175: Oplossingen Methodiek van de Informatica

HOOFDSTUK 17. EXAMEN JUNI 2003 168

– contra: Attributen en methodes die niet tot de klasse zelf behoren ofniet een subklasse zijn van de beschouwde klasse kunnen niet recht-streeks opgeroepen worden. Ook dit kan uiteraard weer opgelostworden door accessor-methodes te voorzien

Algoritme schrijven

pub l i c s t a t i c i n t [ ] unie ( i n t [ ] x , i n t [ ] y ){

// t e l hoevee l e r n i e t dubbel z i j n van de tweede r i ji n t aanta l = y . l ength ;

f o r ( i n t i = 0 ; i != x . l ength ; i++){

i f ( l i n e a i rZo ek en (y , x [ i ] ) ){

aantal−−;}

}

i n t [ ] unie = new in t [ x . l ength+aanta l ] ;

// ze t a l l e elementen van de e e r s t e r i j in de unief o r ( i n t i =0; i !=x . l ength ; i++){

unie [ i ]=x [ i ] ;}

// voeg nu de elementen d i e n i e t dubbel voorkomen inde tweede r i j toe aan de unie

i n t k=0;

whi l e ( k!= aanta l ){

f o r ( i n t i =0; i !=y . l ength ; i++){

i f ( l i n e a i rZo ek en (x , y [ i ] )==f a l s e ){

unie [ x . l ength+k]=y [ i ] ;k++;

}}

}re turn unie ;

Waarbij de code voor lineairZoeken1

/∗∗1Ik heb het lineair zoeken in een aparte methode staan omdat ik deze ook makkelijk kon

herbruiken voor andere algoritmes. Toont trouwens toch ook mooi OOP aan.

Page 176: Oplossingen Methodiek van de Informatica

HOOFDSTUK 17. EXAMEN JUNI 2003 169

∗ L inea i r zoeken∗ @param in t zoekwaarde∗ @param in t [ ] r i j∗ @return boolean true / f a l s e∗/

pub l i c s t a t i c boolean l i n e a i rZo ek en ( i n t [ ] r i j , i n tzoekwaarde )

{boolean inR i j = f a l s e ;

f o r ( i n t i = 0 ; i < r i j . l ength ; i++){

i f ( zoekwaarde == r i j [ i ] ){

i nR i j = true ;}

}re turn inR i j ;

}

/∗∗∗ Methode d i e twee ar rays van i n t e g e r s samenvoegt to t∗ een array , waarb i j de dubbels e r u i t gehaald worden∗ @param in t [ ] x , i n t [ ] y∗ @return i n t [ ] unie∗/

pub l i c s t a t i c i n t [ ] un ieBi s ( i n t [ ] x , i n t [ ] y ){

// t e l hoevee l e r n i e t dubbel z i j n van de tweede r i ji n t aanta l = y . l ength ;

f o r ( i n t i = 0 ; i != x . l ength ; i++){

i f ( b ina i rZoeken (y , x [ i ] ) ){

aantal−−;}

}

i n t [ ] unie = new in t [ x . l ength+aanta l ] ;

// ze t a l l e elementen van de e e r s t e r i j in de unief o r ( i n t i =0; i !=x . l ength ; i++){

unie [ i ]=x [ i ] ;}

Page 177: Oplossingen Methodiek van de Informatica

HOOFDSTUK 17. EXAMEN JUNI 2003 170

// voeg nu de elementen d i e n i e t dubbel voorkomen inde tweede r i j toe aan de unie

i n t k=0;

whi l e ( k!= aanta l ){

f o r ( i n t i =0; i !=y . l ength ; i++){

i f ( b ina i rZoeken (x , y [ i ] ) == f a l s e ){

unie [ x . l ength+k ] = y [ i ] ;k++;

}}

}re turn unie ;

}

Waarbij binairZoeken dus volgende methode is

/∗∗∗ Bina i r zoeken∗ @param in t zoekwaarde∗ @param in t [ ] r i j∗ @return boolean true / f a l s e∗/

p r i va t e boolean bina i rZoeken ( i n t [ ] r i j , i n t zoekwaarde ){

i n t low = 0 ;i n t high = r i j . length −1;i n t mid ;

whi l e ( low!=high ){

mid = ( low+high ) /2 ;

i f ( zoekwaarde <= r i j [ mid ] ){

high = mid ;}e l s e{

low = mid + 1 ;}

}re turn ( r i j [ low ] == zoekwaarde ) ;

}

Schetsen geheugentoestand

Page 178: Oplossingen Methodiek van de Informatica

HOOFDSTUK 17. EXAMEN JUNI 2003 171

Figuur 17.1: Toestand geheugen na checkpoint 1

Page 179: Oplossingen Methodiek van de Informatica

HOOFDSTUK 17. EXAMEN JUNI 2003 172

Figuur 17.2: Toestand geheugen na checkpoint 2

Page 180: Oplossingen Methodiek van de Informatica

HOOFDSTUK 17. EXAMEN JUNI 2003 173

Figuur 17.3: Toestand geheugen na checkpoint 3

Page 181: Oplossingen Methodiek van de Informatica

HOOFDSTUK 17. EXAMEN JUNI 2003 174

// i n t n i s r eeds bepaald door de gebru ike r// p r e c ond i t i e : n>=0

in t k , prod ;// i n i t i a l i s a t i ek = 0 ;prod = 0 ;

// i nva r i an t e r e l a t i e : prod = 7∗k// t r i v i a a l geva l : 0 = 7∗0

whi l e ( k!=n){

prod = prod + 7 ;// i nva r i an t e r e l a t i e : prod = 7∗( k+1)k = k + 1 ;// i nva r i an t e r e l a t i e : prod = 7∗( k+1) && k++ ⇒

prod = 7∗k}

// e i n d r e l a t i e : prod = 7∗n// po s t c ond i t i e :// prod = 7 · n = 7 · k︸︷︷︸

invariante relatie

// AND// k = n︸ ︷︷ ︸

!test

Page 182: Oplossingen Methodiek van de Informatica

Deel IV

Bijlagen

175

Page 183: Oplossingen Methodiek van de Informatica

Bijlage A

Oefeningen op algoritmen

Dit deel bevat een aantal oefeningen op algoritmen van vorig jaar.

176

Page 184: Oplossingen Methodiek van de Informatica

Redeneren over algoritmes "You could test for literally centuries and not discover an error,"

James L. Caldwell

Overzicht Deze tekst behandelt twee onderwerpen waaraan aandacht moet besteed worden bij het ontwikkelen van computerprogramma’s: de correctheid en de (tijds)complexiteit van de gebruikte algoritmes. Het eerste onderwerp heeft te maken met het formeel aantonen van de juistheid van een algoritme. Dit komt erop neer dat een algoritme bewezen wordt. Het bewijzen van een algoritme betekent dat er wordt aangetoond dat het algoritme aan een aantal eigenschappen voldoet. Deze eigenschappen geven meestal het verband weer dat geldt tussen de invoer van het algoritme en de uitvoer ervan - namelijk het resultaat van de berekeningen – of de eindigheid van het algoritme. Het tweede onderwerp behandelt de tijdscomplexiteit van algoritmes. Kortweg gezegd kan je aan de hand van de theorie rond tijdscomplexiteit bepalen hoe de uitvoeringstijd van een algoritme zich verhoudt tot de grootte van de invoer. Naast tijdscomplexiteit bestaat er ook ruimtecomplexiteit, deze complexiteit geeft het geheugenverbruik weer van een programma of algoritme. Over deze laatste vorm van complexiteit gaan we het in deze bundel niet hebben.

Correctheid van algoritmes Een methode die vaak gebruikt wordt om de correctheid van programma’s (deels) aan te tonen is het programma testen. Over het testen van software is al veel geschreven en er bestaan verschillende soorten testen, maar ze hebben allemaal als eigenschap dat het programma een aantal keer dient uitgevoerd te worden. Testen is een uitstekende manier om fouten op te sporen, maar je kan er (meestal) de correctheid van je programma niet mee bewijzen. Dit komt omdat je het programma zou moeten testen voor alle mogelijke invoer, wat in de praktijk meestal onmogelijk is. Stel dat je een methode isPriem() hebt die nagaat of een getal priem is of niet. Als invoer neemt isPriem() natuurlijke getallen > 1 aan en als resultaat geeft het true of false terug al naargelang het getal priem of niet priem is. We kunnen deze methode testen: 2 -> isPriem() -> true 3 -> isPriem() -> true 4 -> isPriem() -> false ... -> isPriem() -> ... Vermits er oneindig veel natuurlijke getallen zijn is het niet doenbaar om je programma voor elk getal te testen! Tests worden vaak gebruikt en zijn heel belangrijk bij het ontwerpen van software. Maar deze aanpak geeft dus nooit 100% garantie... Gelukkig bestaat er een alternatieve manier: het gebruik van correctheidsbewijzen. Een correctheidsbewijs is een formeel bewijs van de correctheid van een algoritme. Dit bewijs toont aan dat het algoritme zich correct gedraagt en dit onder eender welke invoer. Dankzij correctheidsbewijzen heb je dus wel 100% garantie dat je code correct is.

Page 185: Oplossingen Methodiek van de Informatica

Correctheidsbewijzen worden ondermeer gebruikt voor kritische software. Kritische software is software die je bijvoorbeeld terugvindt in kerncentrales, vliegtuigen, seinhuizen (trein, metro, ...), enzovoorts. Voor dit type software is het van belang dat je 100% zekerheid hebt van de juistheid van je algoritme of programma. Daarnaast kan je correctheidsbewijzen ook gebruiken voor jezelf of voor anderen, om aan te tonen dat je programma correct is, maar ook, en dat is niet minder belangrijk, om je te helpen bij het opbouwen van een programma.

Enkele begrippen Vooraleer we ons gaan concentreren op correctheidsbewijzen is het belangrijk volgende termen kort te verklaren: Preconditie

Een preconditie is een voorwaarde waaraan moet voldaan zijn vooraleer een welbepaald stuk code mag uitgevoerd worden. Precondities worden vaak als commentaar aan methodes toegevoegd. Bijvoorbeeld: /** * Deze methode wordt gebruikt om een robot vooruit te * te laten rijden.

* * PARAMETER: x stelt het aantal centimeter voor * * PRECONDITIE: 0 <= x && x <= 1000 */

public void gaVooruit(int x) { ... }

Bovenstaande preconditie geeft weer waaraan de oproeper van deze methode zich moet houden: de parameter die hij meegeeft moet tussen 0 en 1000 centimeter liggen.

Precondities worden niet enkel gebruikt om methodes te documenteren; je kan ze ook gebruiken om blokken code mee te documenteren. We zullen dit in deze bundel bijvoorbeeld gebruiken bij de while-lus.

Postconditie

Een postconditie is een voorwaarde waaraan voldaan is nadat een stuk code werd uitgevoerd. Postcondities worden ook vaak als commentaar aan methodes toegevoegd; hier geven ze informatie aan de potentiële gebruiker over het effect van de methode. Bijvoorbeeld: /** * Deze methode wordt gebruikt om de druk in een ketel te * laten toenemen.

*/ public void verhoogDruk() { ... } /** * POSTCONDITIE: druk is met 1 bar verhoogd EN

* alarmsignaal indien druk > 15 bar */

Page 186: Oplossingen Methodiek van de Informatica

Postcondities worden niet enkel bij methodes gebruikt; je kan ze ook toevoegen aan blokken code (zie ook de while-lus).

Invariant

Een invariant is een conditie waaraan op een bepaalde plaats in het programma steeds voldaan is. Invarianten kan je bijvoorbeeld toevoegen aan een klasse, dat wil dan zeggen dat alle publieke methodes van deze klasse de invariant doen behouden. Bijvoorbeeld: stel je hebt een klasse GesorteerdeRij die gehele getallen bijhoudt, gesorteerd van klein naar groot.

public class GesorteerdeRij {

/** * INVARIANT: de elementen zijn gesorteerd van klein * naar groot.

*/ ...

/** * Deze methode plaatst een element e in de

* gesorteerde rij. * * PARAMETER: een integer die in de rij moet komen.

*/ public void voegIn(int e) { ... }

/** * Deze methode verwijdert een element e uit de

* gesorteerde rij. * * PARAMETER: een integer die verwijderd moet worden.

*/ public void verwijder(int e) { ... }

/** * Deze methode zoekt naar een element e in de * gesorteerde rij. Geeft true terug als het element * gevonden is, false indien niet.

* * PARAMETER: een integer die gezocht wordt.

*/ public boolean zoek(int e) { ... }

/**

* Aan de hand van deze methode kan je het element op * positie i opvragen. * Vermits de rij gesorteerd is van klein naar groot, * zal dit het i-e kleinste element van de rij zijn.

* * PARAMETER: een integer die de positie aangeeft. */

public int geefElement(int i) { ... } }

Bovenstaande methodes - voegIn(), verwijder(), zoek() en geefElement() - behouden allemaal de klasse-invariant: namelijk dat alle elementen ten allen tijde gesorteerd zijn van klein naar groot.

Page 187: Oplossingen Methodiek van de Informatica

Er zijn ook nog andere vormen van invarianten, waaronder de lus-invariant. Deze zullen we verder in de bundel behandelen.

Structuur van een correctheidsbewijs In deze bundel besteden we aandacht aan correctheidsbewijzen voor lussen (de while-lus). De algemene structuur van een bewijs voor een while-lus ziet er als volgt uit: // Preconditie (optioneel) <initialisatie-opdrachten> //Invariant while (B) { //Invariant AND B <opdrachten> //Invariant } //Postconditie: Invariant AND !B Je ziet meteen dat de invariant een belangrijk concept blijkt te zijn in een correctheidsbewijs. In het geval van een lus is een invariant steeds waar, net voor de lus, in het begin van de lus-body, op het einde van de lus-body en na afloop van de volledige lus. De preconditie kan gebruikt worden om bepaalde condities duidelijk te maken die moeten geldig zijn vóór de lus van start gaat. De postconditie geeft aan wat het resultaat is van de lus. Het vinden van de invariant is het moeilijkste aan een correctheidsbewijs. Eenmaal je deze gevonden hebt, verloopt de rest meestal van een leien dakje. Een mogelijke manier van werken om deze invariant te vinden is te beginnen met de postconditie. De postconditie is de conditie die geldig is na afloop van de lus. Deze conditie geeft eigenlijk weer wat het gewenste eindresultaat is. Het opstellen van de postconditie zou geen probleem mogen zijn, want het heeft geen zin een programma te schrijven als je niet weet wat het eindresultaat moet zijn! Nadien zal je de postconditie moeten herschrijven1 totdat je een postconditie van de vorm: invariant AND !B hebt. Hieruit kan je dan bepalen wat de stopconditie van de lus moet zijn en wat de invariant is van de lus. In het algemeen moet een invariant aan het volgende voldoen: hij moet zwak genoeg zijn zodat je kan aantonen dat de invariant geldig is voordat de lus start en hij moet in combinatie met de stopconditie sterk genoeg zijn om de postconditie aan te tonen. Als je denkt een invariant te hebben gevonden moet je bewijzen dat het wel degelijk een invariant is. Dit komt erop neer eerst en vooral na te gaan of de invariant geldig is net voor de start van de lus . Daarna moet je ook nagaan of de invariant geldig is op het einde van de lus-body. Dit laatste kan je doen door de invloed van elke stap (van de lus-body) op de invariant na te gaan. Als alle stappen doorlopen zijn, zou je terug de invariant moeten bekomen. Op dit moment heb je bewezen dat je algoritme correct is: als de while-lus stopt dan ben je er zeker van dat de postconditie geldig is. Maar er is nog een aspect dat je moet bewijzen: eindigt de lus wel? Dit is een stap die vaak vergeten wordt maar die ook van belang is. Een lus die nooit eindigt betekent dat het programma blijft “hangen”. En dat is iets dat je niet wil tegenkomen als deze lus bijvoorbeeld voorkomt in kernreactor-software.

1 Dit herschrijven kan je doen door een verband te zoeken dat geldt tussen de variabelen van de lus. Meestal is het echter zo dat je al moet nadenken over deze invariant wanneer je de lus aan het ontwik-kelen bent. Want op dat moment redeneer je over alle variabelen die in de lus voorkomen en is het ook het geschikte moment om een verband te zoeken tussen al deze variabelen. Hierop komen we verder nog terug (zie “Beredeneerd ontwerpen van een algoritme”).

Page 188: Oplossingen Methodiek van de Informatica

Het aantonen van de eindigheid van een lus komt erop neer dat je aantoont dat er convergentie is naar de stopconditie. Je moet dus aantonen dat de conditie B ooit onwaar zal zijn. Om samen te vatten moet je dus volgende stappen ondernemen om een algoritme te bewijzen:

- zoek de postconditie - bepaal hieruit een invariant en een stopconditie - toon aan dat de invariant geldig is vóór de lus start - toon aan dat de invariant geldig is na uitvoering van de lus-body - toon aan dat er vooruitgang is naar de stopconditie

Een voorbeeld Stel je hebt een lus die het grootste element in een rij van integers zoekt (met als preconditie dat de rij minstens 1 element moet bevatten): // PRECONDITIE: rij.length >= 1 maximum = rij[0]; i = 1; while ( i != rij.length ) { if ( rij[i] > maximum ) maximum = rij[i]; i++; } Wat is nu het eindresultaat dat we wensen? Informeel kan je het als volgt uitdrukken: na afloop van de lus (i==rij.length) moet in maximum de grootste waarde zitten van de volledige rij. Formeler2 uitgedrukt hebben we: maximum = max(rij[0], …, rij[rij.length – 1]) AND i == rij.length Als we dit wat herschrijven geeft dit: [regel 1] maximum = max(rij[0], …, rij[i - 1]) AND [regel 2] i == rij.length De eerste regel zal dan de invariant zijn, de tweede regel bevat de stopconditie. Bemerk dat de invariant neergeschreven is in functie van de variabelen die in de lus voorkomen (rij, i en maximum) zoals opgemerkt in voetnoot 1 op pagina 4. Eerst en vooral moeten we aantonen dat de invariant geldig is vooraleer de lus start. Het is duidelijk dat maximum = max(rij[0]) triviaal waar is. Vervolgens moeten we nagaan of de invariant op het einde van de lus-body ook opnieuw waar is: ... if ( rij[i] > maximum ) maximum = rij[i]; i++; ...

2 Een invariant wordt meestal uitgedrukt in een wiskundige formule, maar je kan een invariant ook in woorden uitdrukken of aan de hand van een tekening. Het belangrijkste is dat de invariant omvattend, duidelijk en ondubbelzinnig is, want anders kan je natuurlijk niets bewijzen.

Page 189: Oplossingen Methodiek van de Informatica

Op het punt na het if-statement en vóór de ophoging geldt de conditie maximum = max(rij[0], …, rij[i]); onze invariant geldt op dit punt niet. Dit is geen fout; de lus-invariant hoeft niet te gelden in het inwendige van de lus-body. Maar na het uitvoeren van de “i++;”-statement bekomen we opnieuw onze invariant. Uiteindelijk moeten we nog aantonen dat de lus eindigt, of anders gezegd, dat er vooruitgang is naar de stopconditie. Dit is duidelijk het geval vermits i start bij 1, en in elke iteratiestap met 1 verhoogd wordt. Uiteindelijk zal i gelijk worden aan rij.length (waarvan we weten dat deze minstens 1 moet bedragen en eindig is). Om alles eens samen te vatten volgt hier nogmaals de code maar nu met het correctheidsbewijs ervan als commentaar in de code opgenomen: // Preconditie: rij.length >= 1 maximum = rij[0]; i = 1; // Invariant: maximum = max(rij[0], …, rij[i – 1]) while ( i != rij.length ) {

// Invariant: maximum = max(rij[0], …, rij[i – 1]) if ( rij[i] > maximum ) maximum = rij[i];

// maximum = max(rij[0], …, rij[i]) i++;

// Invariant: maximum = max(rij[0], …, rij[i – 1]) } // Postconditie: // maximum = max(rij[0], …, rij[i – 1]) // AND // i == rij.length // Eindigheid: i start op 1 en wordt met 1 verhoogd in elke // stap, om uiteindelijk rij.length te bereiken (welke // minstens 1 is).

Oefening 1: In deze oefening is het de bedoeling dat je zelf de correctheid van een eenvoudig programma probeert te bewijzen. Het programma(atje) berekent nn (met n >0) en plaatst het resultaat in resultaat.

int resultaat = 1;

int teller = 0; while (teller != n) { resultaat = resultaat * n; teller++; }

Oefening 2: Schrijf een programma dat de grootste gemene deler van twee natuurlijke getallen berekent. Bewijs de correctheid van je programma. (hint: gebruik volgende formule: Als x > y dan ggd(x,y) = ggd(x - y, y))

Oefening 3: Deze oefening is ietwat ingewikkelder omdat je gebruik zal moeten maken van twee lussen (waarbij de ene genest is in de andere).

Page 190: Oplossingen Methodiek van de Informatica

Volgend algoritme is het sorteeralgoritme Bubblesort. Eenvoudig gesteld gaat het algoritme ‘bubbelen’: het vergelijkt telkens twee naast elkaar liggende elementen en als het rechtse kleiner is dan het linkse, worden ze omgewisseld. Het ‘bubbelen’ zorgt ervoor dat het grootste element uiterst rechts terechtkomt. Als dit een tweede keer gedaan wordt, komt het tweede grootste rechts op de tweede plaats enzoverder.

Het algoritme bestaat uit een eerste lus die een rij r van rechts naar links doorloopt. Alles wat zich rechts van de huidige positie bevindt is reeds gesorteerd van klein naar groot. Alles wat zich links van de huidige positie bevindt is nog niet gesorteerd, maar elk element in de linkerdeelrij is kleiner dan elk element in de rechterdeelrij (en dus a fortiori kleiner dan het meest linkse element van de rechtse deelrij). In feite bestaat deze rij dus uit twee deelrijen: r1 en r2. Per iteratiestap wordt in de linkerdeelrij (r1) het grootste element van r1 helemaal achteraan in r1 geplaatst (of dus vooraan r2 gezet). Om dit te doen wordt een tweede lus gebruikt die over r1 itereert. Als je dit visueel zou voorstellen zou het net zijn alsof het grootste element ‘sprongetjes’ maakt tot op het einde van r1, waarbij r2 steeds groter wordt en r1 steeds kleiner.

In code uitgedrukt:

int i = r.length; while (i != 0) { int j = 0; while (j != i - 1) { if (r[j+1] < r[j]) {

int temp = r[j+1]; r[j+1] = r[j]; r[j] = temp; } j++; } i--;

} Bewijs de correctheid van deze code. Eerst een tekening maken om te zien wat er gebeurt, zal hierbij zeker helpen.

Beredeneerd ontwerpen van een algoritme In het vorige deel werd vooral aandacht besteed aan het bewijzen van code die vooraf geschreven is. Je kan correctheidsbewijzen (en de daarbij horende invarianten) echter ook gebruiken om een algoritme te ontwerpen, zonder dat je eerst de code neerschrijft. Het gebruik van een beredeneerde methode bij het opbouwen van een algoritme helpt je meer inzicht te krijgen in het algoritme zelf. En het zal ook sneller tot een correct algoritme leiden. Ook hier kan je een aantal stappen volgen die zullen leiden tot een correct algoritme:

- Bepaal eerst de vereiste precondities: deze precondities geven aan wat je algoritme verwacht van de gebruiker ervan. Om je programma robuust te maken schrijf je best ook vooraf code die nagaat of er wel aan de precondities is voldaan.

- Bepaal de gewenste postconditie: schrijf eens in woorden neer wat het gewenste eindresultaat is van je programma. Als je dit niet kan doen, dan heeft het ook geen zin om een programma te maken! Eenmaal je dit in woorden hebt gedaan kan je proberen het eindresultaat te formaliseren.

- Bepaal een mogelijke invariant: herschrijf het gewenste eindresultaat zodat je een duidelijke invariant naar voren ziet komen. Dit is de moeilijkste stap. Zoek naar de

Page 191: Oplossingen Methodiek van de Informatica

variabelen die je nodig hebt in je lus en zorg ervoor dat de invariant duidelijk het verband weergeeft dat tussen deze variabelen van toepassing is.

- Bepaal een oplossingsmethode: schrijf nu de code neer van de lus-body. Deze code moet je zodanig schrijven dat de invariant behouden blijft en dat er vooruitgang is naar de stopconditie.

- Zorg voor de nodige initialisaties: schrijf de code die nodig is vooraleer de lus start. Let erop dat de initialisaties ervoor zorgen dat de invariant van in het begin waar is.

- Bepaal de test die de lus doet stoppen: deze test zal je dan gebruiken als stopconditie voor je lus.

Eenmaal je bovenstaande stappen overlopen hebt moet je nog de invariant bewijzen en de eindigheid van je programma aantonen. Dit zou geen probleem mogen zijn, vermits je dit al deels gedaan hebt in de vorige stappen.

Oefening 4: Bedenk een programma dat de faculteit van een getal n berekent. Doe dit aan de hand van bovenstaande stapsgewijze methode.

Page 192: Oplossingen Methodiek van de Informatica

Complexiteit van algoritmes Heel de cursus door hebben we gezien dat de computer bepaalde taken die wij hem willen laten uitvoeren niet rechtstreeks kan: er is geen standaard bevel in Java om hem dit te laten doen. Daarom moeten we zelf dergelijke ‘hoog-niveau’ opdrachten (bvb. beheer een adressenbestand) vertalen in een opeenvolging van ‘laag-niveau’ bevelen die in Java wel voorzien zijn (if (persoon.aantalKinderen > 0) ...). Je hebt ook al ondervonden dat er vaak verschillende oplossingen zijn voor eenzelfde probleem. Wanneer je meerdere oplossingen ziet, moet je kunnen afwegen wat de voor- en nadelen van elke oplossing zijn. Hierbij moet je onder andere rekening houden met de leesbaarheid, algemeenheid en aanpasbaarheid van de oplossing. Maar ook de snelheid van uitvoering is een belangrijk gegeven. De term ‘complexiteit’ van een algoritme heeft een iets andere betekenis dan wat je intuïtief zou vermoeden: het is niet omdat een stukje programma er ingewikkeld uit ziet dat het een hoge complexiteit heeft. Complexiteit drukt ook niet uit hoe lang een programma precies zal lopen. De (tijds)complexiteit van een algoritme geeft wel weer hoe de grootte van de invoer en de uitvoeringstijd van het algoritme zich tot elkaar verhouden. Anders uitgedrukt: wanneer we een grafiek van de uitvoeringstijd zouden maken, met op de x-as de grootte van de invoer, en op de y-as de tijd die het algoritme nodig heeft om deze invoer te verwerken, dan is de complexiteit van het algoritme de functie die deze grafiek het best benadert. Bijna altijd kijkt men echter naar de grootte-orde van de complexiteit: de macht van de grootste factor van de functie die de grafiek beschrijft.

Nemen we als voorbeeld een programma dat als invoer een aantal gesorteerde rijen krijgt en als resultaat al deze rijen moet samenmengen in 1 grote gesorteerde rij. De grafiek hiernaast zou bijvoorbeeld de tijd kunnen zijn dat het sorteerprogramma nodig heeft om 10000 elementen te sorteren, met de grootte van de invoer het aantal rijen waarover de invoer verspreid is. We zien dat als alles in 1 rij aangeboden wordt, we gewoon dit kunnen teruggeven, en dat er dus weinig

berekeningstijd nodig is (1 seconde). Wanneer de invoer echter in 2 rijen zit, zijn al 3 seconden nodig. Hieruit kunnen we echter weinig besluiten over de complexiteit: de complexiteit is immers het asymptotisch gedrag van de uitvoeringstijd. Wanneer we ook van enkele andere invoerwaarden de tijden opmeten (zie grafiek hiernaast) zien we dat de tijden kwadratisch toenemen. De functie die deze grafiek benadert is f(n) = n2 – 1 en dat is dus van grootte-orde n2. We zeggen dus dat de tijdscomplexiteit van dat algoritme O(n2) is. In praktijk is het echter moeilijk om elk algoritme te gaan implementeren en testen met verschillende invoer, de tijden opmeten, in grafiek zetten en een benaderende functie zoeken om de complexiteit te kunnen bepalen. In de rest van dit hoofdstuk gaan we illustreren hoe je aan de hand van alleen de programmacode de complexiteit kan bepalen. Een eerste stap is het bepalen van de probleemgrootte: in functie van welke variabele(n) we de complexiteit zullen berekenen. Voor de meeste kleine algoritmes is dit voor de hand liggend: wanneer we de complexiteit voor het sorteren van een rij berekenen is dit in functie van de lengte van de rij en niet bvb in functie van de grootste waarde die in de rij voorkomt. Voor grotere algoritmes moet je hier over nadenken. De complexiteit hangt af van de

0

5

10

15

20

25

30

35

1 2 3 4 5

grootte invoer

tijd

Page 193: Oplossingen Methodiek van de Informatica

variabelen waarin we de complexiteit uitdrukken, en je moet dus steeds duidelijk maken in functie van welke variabele je de complexiteit uitdrukt! In de volgende paragrafen gaan we enkele methodes onderzoeken die als parameter een rij van integers krijgen. Let op: de invoer is in deze voorbeelden al gegeven, dus het inlezen van de invoer is niet nodig in de methode, en beïnvloedt bijgevolg de complexiteit niet. De probleemgrootte is de lengte van de rij, die we vanaf nu n noemen

Voorbeeld 1: geef de lengte van de rij terug public int geefLengte(int[] rij) { return rij.length; }

In Java is een rij een object, en de lengte van een rij is een attribuut van dit object. Het opvragen van de waarde van een attribuut gebeurt in constante tijd. Ook de return van een waarde gebeurt in constante tijd. De uitvoeringstijd T kunnen we als volgt berekenen: T = Tattribuut opvragen + Treturn = a + b = O(1)

Dit is de meest wenselijke tijdscomplexiteit: hoe groot de invoer ook wordt, het zal altijd even lang duren om de oplossing te berekenen. Helaas zijn er weinig ‘interessante’ algoritmes die een dergelijke tijdscomplexiteit hebben.

Voorbeeld 2: hoeveel nullen in een gesorteerde rij De parameter die we meekrijgen is een gesorteerde rij van positieve integers (dus geen negatieve getallen). We moeten berekenen hoeveel keer 0 voorkomt in deze rij. We doen dit door de index van de ‘laatste’ 0 te zoeken; vermits de rij gesorteerd is geeft dit getal (+ 1 natuurlijk, vermits er vanaf 0 geteld wordt) aan hoeveel nullen er zijn. We gebruiken het idee van binair zoeken: we nemen telkens het middelste van de rij, als dat element de laatste 0 is (het element is 0 en het volgende element is niet nul of bestaat niet) hebben we een oplossing, anders halveren we de rij: we nemen het linker deel als het middelste element groter dan 0 was, anders het rechter deel. Hoeveel tijd heeft dit algoritme nodig? Dat hangt er natuurlijk van af hoe snel de laatste 0 gevonden wordt. Als de laatste 0 net in het midden van de rij staat vinden we deze direct, en is de tijd nodig onafhankelijk van de lengte van de rij: O(1). Dit is echter het optimale geval. We kunnen ons afvragen wat het slechtst mogelijke geval is. Dit is de situatie waarbij we onze deelrij telkens opnieuw in 2 moeten splitsen totdat we uiteindelijk bij een deelrij van lengte 1 uitkomen. Dit doet zich bvb voor indien er geen nullen (of allemaal nullen) in de rij zitten. Stel dat we beginnen met een rij van lengte 8. Hoe vaak moeten we deze rij halveren om een rij van lengte 1 uit te komen? 8/2 =4, 4/2 = 2, 2/2 = 1 Er zijn dus drie stappen nodig, omdat 8/(23) = 1. Meer algemeen moet een rij met n elementen i keer gehalveerd worden om een rij van lengte 1 te bekomen, met i zodanig dat n/(2i) = 1 en dus i = log2n. In het slechtste geval zijn er dus log2n halveringsstappen nodig in onze zoekalgoritme. Elke stap bestaat echter uit een constant aantal bevelen en neemt dus een constante tijd in beslag:

0

0.5

1

1.5

2

2.5

1 2 3 4 5 6 7 8

grootte rij

tijd

Page 194: Oplossingen Methodiek van de Informatica

T = Tinitialisatie + (log2n * Thalveringsstap) = a + (log2n * b) = O(log2n)

In het slechtste geval is de complexiteit dus O(log2 n). Vele algoritmes die bvb elementen zoeken of invoeren in gesorteerde rijen hebben deze tijdscomplexiteit. Hoewel niet zo goed als O(1) zijn O(log2n) algoritmes toch erg snel. Stel dat we bvb het bovenstaande algoritme uitvoeren met een rij van 10000 elementen, dan moeten er in het slechtst mogelijke geval toch maar 24 stappen in het algoritme gezet worden!

Oefening 5: een meer voor de hand liggende oplossing voor bovenstaand probleem is gewoon de gegeven rij vanaf het begin doorlopen totdat we een element verschillend van 0 tegenkomen. Bereken de ‘slechtste geval’ complexiteit van dat

algoritme.

Voorbeeld 3: hoeveel nullen in een niet gesorteerde rij? Wanneer we bovenstaande opgave moeten herhalen in een rij die niet gesorteerd is, zit er niets anders op dan alle elementen in de rij te bekijken, en het aantal nullen tellen: public int tel0(int [] rij) { int aantal = 0; for (int i=0;i!=rij.length; i++) { if (rij[i]==0) {aantal++;} } return aantal; } We zien dat er een probleem is bij het berekenen van de complexiteit. In de lus zit een if: soms zal het then-deel uitgevoerd worden, soms niet. Hoe berekenen we van zoiets de complexiteit? We bekijken weeral het beste en het slechtste geval. In het beste geval zit er geen enkele 0 in de rij, en wordt het bevel in de then-tak nooit uitgevoerd. De lus zelf wordt n keer uitgevoerd (met n = rij.length):

T = Tinitialisatie + Treturn + n * (Ti!=rij.length + Ti++ + Trij[i]==0) = a + b + n * (c + d + e) = O(n)

In het slechtste geval bestaan de rij allemaal uit nullen, zodat het then deel altijd uitgevoerd wordt:

T = Tinitialisatie + Treturn + n * (Ti!=rij.length + Ti++ + Trij[i]==0 + Taantal++) = a + b + n * (c + d + e + f) = O(n)

0

0.1

0.2

0.3

0.4

0.5

0.6

0.7

0.8

0.9

1

1 2 3 4 5 6 7 8

grootte rij

tijd

Page 195: Oplossingen Methodiek van de Informatica

)(nO

)(nO

Dit heeft dus geen invloed op de grootte-orde van de tijdscomplexiteit, deze is steeds O(n). Deze complexiteit komt heel frequent voor: vaak moet men immers alle elementen in de invoer 1 keer (of een ander constant aantal keer) bekijken alvorens het probleem te kunnen oplossen.

Rekenen met grootte-ordes Vaak bestaat je algoritme uit kleinere onderdelen waarvan je elk apart de complexiteit kan bepalen, wat meestal heel wat gemakkelijker is dan direct van het grote geheel de complexiteit te berekenen. Maar hoe bepaal je de complexiteit van het geheel wanneer je de complexiteit van alle onderdelen kent? Dit is heel eenvoudig zolang je er aan denkt dat bvb een tijdscomplexiteit van O(n) betekent dat de tijd die nodig is a * n + b bedraagt, met a en b constanten. Verder moet je beseffen dat 2 subalgoritmes in sequentie betekent dat we hun tijden gewoon optellen, terwijl bij een subalgoritme die in een lus zit we de complexiteit van de lus moeten vermenigvuldigen met de complexiteit van de subalgoritme. We illustreren dit aan de hand van twee eenvoudige codefragmenten. In het eerste codefragment zoeken we eerst het maximum en vervolgens het minimum in een gegeven rij van integers; we weten dat de rij minstens 1 element bevat. // maximum zoeken int max = rij[0]; for (int i=1; i!=rij.length;i++) { if (rij[i]>max) {max = rij[i];} } // minimum zoeken int min = rij[0]; for (int i=1; i!=rij.length;i++) { if (rij[i]<min) {min = rij[i];} } Beide lussen overlopen de rij 1 keer, en hebben dus elk een complexiteit van O(n). Vermits de 2de lus niet in de 1e lus genest is, zal de tijd die nodig om zowel het minimum al het maximun te vinden is gewoon de som zijn van de tijden die elke lus afzonderlijk nodig heeft:

T = Tlus maximum zoeken + Tlus minimum zoeken = O(n) + O(n) = a*n + b + c*n + d = (a+c)*n + (b+d) = O(n)

Oefening 6: stel dat de 2de lus een complexiteit van O(log2n) zou hebben, wat zou dan de complexiteit van dat algoritme zijn?

0

1

2

3

4

5

6

7

8

9

1 2 3 4 5 6 7 8

grootte rij

tijd

Page 196: Oplossingen Methodiek van de Informatica

)(nO

We zien dus dat de uitvoeringstijd van twee algoritmes in sequentie de som is van hun tijden. De grootte-orde van de complexiteit is bijgevolg het maximum van de grootte-ordes van de complexiteit van beide algoritmes. Wanneer lussen genest zijn is dit anders. Bekijken we bijvoorbeeld dit codefragment dat voor een gegeven rij van integers elk element uitschrijft, samen met hoe vaak die waarde voorkomt in de rij: for (i=0;i!=rij.length;i++) { teller = 0; for (j=0;j!=rij.length;j++) { if (rij[i]==rij[j]) {teller++;} } System.out.println(“Getal “ + i + “ komt “ + teller + “ keer voor.”); } Van de binnenste for-lus hebben we de complexiteit al berekend (zie ‘aantal nullen in niet gesorteerde rij’), deze is O(n). Nu zit deze lus echter genest in een lus die zelf ook n keer uitgevoerd wordt: elke keer als de buitenste lus een keer uitgevoerd wordt, wordt de binnenste lus n keer uitgevoerd. Bijgevolg is de tijd die nodig is:

T = n * (Tteller=0 + Tbinnenste for-lus + TSystem.out.println) = n * (a + O(n) + b) = n * (a + (c*n +d) + b) = n*(a+d+b) + c*n2 = O(n2)

De complexiteit is dus in dit geval het product van de grootte-ordes van de complexiteit van beide geneste lussen.

Oefening 7: gegeven is een methode public int[] voegInGesorteerdeRij(int[] rij, int

element) die als parameters een gesorteerde rij van lengte n en een integer neemt, en als uitvoer een rij van lengte n+1 zou geven, namelijk door het opgegeven element op de juiste plaats in te voegen in de gegeven rij. Stel dat deze methode dit in O(log2n) zou kunnen. Schrijf dan een algoritme dat van deze methode gebruik maakt en dat een opgegeven ongesorteerde rij van integers als invoer neemt en als uitvoer deze rij gesorteerd teruggeeft. De complexiteit van het totale algoritme moet O(n * log2n) zijn. Opgelet: je moet de methode voegInGesorteerdeRij niet zelf schrijven!

Oefening 8: algoritmes A en B zoeken beide dubbels in een rij van gegeven getallen. Voor een rij van 100 getallen heeft algoritme A 10 seconden nodig, algoritme B 20 seconden. Kunnen we hieruit afleiden dat de complexiteit van

algoritme B hoger is dan die van algoritme A? Leg uit!

Oefening 9: algoritme A zoekt dubbels in een rij van gegeven getallen. Voor een rij van 10 getallen heeft het 10 seconden nodig, voor een rij van 20 getallen 20 seconden. Kunnen we hieruit besluiten dat de complexiteit van dit algoritme O(n)

is? Leg uit!

Page 197: Oplossingen Methodiek van de Informatica

Oefening 10: Als vakantiejob moet je ingescande documenten vergelijken. Hiervoor zijn er 2 algoritmes: A

(streepjeslijn, O(log2n)) en B (volle lijn, O(n)) waarvan je hiernaast een grafiek van de uitvoeringstijden ziet: de x-as is het aantal elementen dat gelijktijdig met elkaar vergeleken wordt, de y-as de tijd die hiervoor nodig is. Indien je telkens 2 documenten met elkaar moet vergelijken, en je per document betaald wordt, welk algoritme zou je dan gebruiken? Indien de prof deze software zou gebruiken om gelijktijdig 400 examenkopijen met elkaar te vergelijken, welk algoritme zal hij dan verkiezen?

Oefening 11: A) je kan n*a berekenen door a n keer bij zichzelf op te tellen. Schrijf een methode public int maal(int a, int n) die op deze manier een product uitrekent.

B) Probeer dit algoritme te wijzigen zodat de complexiteit daalt (hint: 4*a = (a+a) + (a+a)). Je mag evenwel geen gebruik maken van de in Java ingebouwde vermenigvuldiging. Je mag wel gebruik maken van uitdrukkingen van de vorm x / 2 en x % 2. De eerste uitdrukking geeft het quotiënt en de tweede de rest bij deling door twee. (Deze bewerkingen kunnen zeer efficiënt geïmplementeerd worden op machines die getallen binair voorstellen.) Bereken van dit nieuwe algoritme de complexiteit. C) Analoog aan bovenstaande methode kan je ook de machtsverheffing herdefiniëren aan de hand van de vermenigvuldiging. Deze methode werd in de les al gezien. Gebruik nu deze methode in het schrijven van een methode die de waarde van een veelterm (bvb 3x3 + 5x2 – 7x –42) uitrekent. Deze methode neemt als parameters een rij van integers die de coëfficiënten van de veelterm voorstelt (in dit vb [3,5,-7,-42]) en een double die de waarde van x is waarvoor we de veelterm willen uitrekenen. Als terugkeerwaarde wordt een double gegeven: het resultaat van de evaluatie van de veelterm. Bereken van dit algoritme de complexiteit. D) Implementeer tot slot het evaluatieschema van Horner (3x3 + 5x2 – 7x – 42 = (((3)*x + 5)*x –7)*x – 42 ) en bereken de complexiteit van dit algoritme.

2

2.5

3

3.5

4

4.5

5

1 2 3 4

A

B

Page 198: Oplossingen Methodiek van de Informatica

Bijlage B

Uitgewerktvoorbeeldexamen augustus2004

Dit deel bevat wat scans van het het examen augustus 2004, zoals uitgewerktin de oefenzitting.

191

Page 199: Oplossingen Methodiek van de Informatica
Page 200: Oplossingen Methodiek van de Informatica
Page 201: Oplossingen Methodiek van de Informatica
Page 202: Oplossingen Methodiek van de Informatica
Page 203: Oplossingen Methodiek van de Informatica
Page 204: Oplossingen Methodiek van de Informatica
Page 205: Oplossingen Methodiek van de Informatica
Page 206: Oplossingen Methodiek van de Informatica
Page 207: Oplossingen Methodiek van de Informatica
Page 208: Oplossingen Methodiek van de Informatica
Page 209: Oplossingen Methodiek van de Informatica
Page 210: Oplossingen Methodiek van de Informatica
Page 211: Oplossingen Methodiek van de Informatica
Page 212: Oplossingen Methodiek van de Informatica

Bijlage C

Een aantal interessantealgoritmes

Bijgevoegd een klasse met een aantal interessante algoritmes, zoals gevraagdop vorige examens. In feite horen ze dus bij de oplossingen van de examenvra-gen, maar omdat het een werkend geheel vormt, staat de methodes allemaalhier bijeen. Het zelf uitvoeren van de methodes is uiteraard het interessantste,zie source-code.

Listing C.1: klasse Algorithms/∗∗ Algorithms . java∗∗ Created on 15 jun i 2006 , 13 :39∗∗/

package a lgor i thms ;

/∗∗∗ Probeer een aanta l a l go r i tmes u i t voor examen MI

vo r i g e j a r en∗ @author Mart i jn∗/

pub l i c c l a s s Algorithms{

/∗∗ Creates a new in s tanc e o f Algorithms ∗/pub l i c Algorithms ( ){

t e s tA lgo ( ) ;}

/∗∗∗ Test the s e l e c t e d a lgor i thms∗/

205

Page 213: Oplossingen Methodiek van de Informatica

BIJLAGE C. EEN AANTAL INTERESSANTE ALGORITMES 206

p r i va t e void te s tA lgo ( ){

i n t [ ] x = {2 ,5 , 8 , 16 , 23 , 25 , 45 , 64} ;i n t [ ] y = {2 ,5 , 8 , 15 , 23 , 25 , 46 , 64} ;

System . out . p r i n t l n ( ”Kwadraatparen eenvoudig ” ) ;aantalKwadraatParen (x ) ;

System . out . p r i n t l n ( ”KwadraatParen b i n a i r ” ) ;aantalKwadraatParenBis ( x ) ;

System . out . p r i n t l n ( ”Unie eenvoudig ” ) ;pr intUnie (x , y ) ;

System . out . p r i n t l n ( ”Unie b i n a i r ” ) ;pr intUnieBi s (x , y ) ;

System . out . p r i n t l n ( ”Dubbel eenvoudig ” ) ;pr intDubbel (x , y ) ;

System . out . p r i n t l n ( ”Dubbel b i n a i r ” ) ;pr intDubbelBis (x , y ) ;

}

pr i va t e void aantalKwadraatParen ( i n t [ ] x ){

i n t aanta l = 0 ;

f o r ( i n t i = 0 ; i < x . l ength ; i++){

f o r ( i n t j = 0 ; j < x . l ength ; j++){

i f ( x [ i ]∗ x [ i ] == x [ j ] ){

aanta l++;}

}}System . out . p r i n t l n ( aanta l ) ;

}

pr i va t e void aantalKwadraatParenBis ( i n t [ ] x ){

i n t aanta l = 0 ;i n t gezocht ;

f o r ( i n t i =0; i !=x . l ength ; i++){

gezocht = x [ i ]∗ x [ i ] ;

Page 214: Oplossingen Methodiek van de Informatica

BIJLAGE C. EEN AANTAL INTERESSANTE ALGORITMES 207

i n t low = 0 ;i n t high = x . length −1;i n t mid ;

whi l e ( low!=high ){

mid = ( low+high ) /2 ;

i f ( gezocht <= x [ mid ] ){

high = mid ;}e l s e{

low = mid + 1 ;}

}

i f ( x [ low ] == gezocht ){

aanta l++;}

}System . out . p r i n t l n ( aanta l ) ;

}

/∗∗∗ Methode d i e twee ar rays van i n t e g e r s samenvoegt

to t∗ een array , waarb i j de dubbels e r u i t gehaald

worden∗ @param in t [ ] x , i n t [ ] y∗ @return i n t [ ] unie∗/

p r i va t e i n t [ ] unie ( i n t [ ] x , i n t [ ] y ){

// t e l hoevee l e r n i e t dubbel z i j n van de tweeder i j

i n t aanta l = y . l ength ;

f o r ( i n t i = 0 ; i != x . l ength ; i++){

i f ( l i n e a i rZo ek en (y , x [ i ] ) ){

aantal−−;}

}

i n t [ ] unie = new in t [ x . l ength+aanta l ] ;

Page 215: Oplossingen Methodiek van de Informatica

BIJLAGE C. EEN AANTAL INTERESSANTE ALGORITMES 208

// ze t a l l e elementen van de e e r s t e r i j in deunie

f o r ( i n t i =0; i !=x . l ength ; i++){

unie [ i ]=x [ i ] ;}

// voeg nu de elementen d i e n i e t dubbel voorkomenin de tweede r i j toe aan de unie

i n t k=0;

whi l e ( k!= aanta l ){

f o r ( i n t i =0; i !=y . l ength ; i++){

i f ( l i n e a i rZo ek en (x , y [ i ] )==f a l s e ){

unie [ x . l ength+k]=y [ i ] ;k++;

}}

}re turn unie ;

}

/∗∗∗ pr in t unie∗/

p r i va t e void pr intUnie ( i n t [ ] x , i n t [ ] y ){

i n t [ ] z = unie (x , y ) ;pr intArray ( z ) ;

}

/∗∗∗ Methode d i e twee ar rays van i n t e g e r s samenvoegt

to t∗ een array , waarb i j de dubbels e r u i t gehaald

worden∗ @param in t [ ] x , i n t [ ] y∗ @return i n t [ ] unie∗/

p r i va t e i n t [ ] un ieBi s ( i n t [ ] x , i n t [ ] y ){

// t e l hoevee l e r n i e t dubbel z i j n van de tweeder i j

i n t aanta l = y . l ength ;

f o r ( i n t i = 0 ; i != x . l ength ; i++){

Page 216: Oplossingen Methodiek van de Informatica

BIJLAGE C. EEN AANTAL INTERESSANTE ALGORITMES 209

i f ( b ina i rZoeken (y , x [ i ] ) ){

aantal−−;}

}

i n t [ ] unie = new in t [ x . l ength+aanta l ] ;

// ze t a l l e elementen van de e e r s t e r i j in deunie

f o r ( i n t i =0; i !=x . l ength ; i++){

unie [ i ]=x [ i ] ;}

// voeg nu de elementen d i e n i e t dubbel voorkomenin de tweede r i j toe aan de unie

i n t k=0;

whi l e ( k!= aanta l ){

f o r ( i n t i =0; i !=y . l ength ; i++){

i f ( b ina i rZoeken (x , y [ i ] ) == f a l s e ){

unie [ x . l ength+k ] = y [ i ] ;k++;

}}

}re turn unie ;

}

/∗∗∗ pr in t unie∗/

p r i va t e void pr intUnieBi s ( i n t [ ] x , i n t [ ] y ){

i n t [ ] z = unieBi s (x , y ) ;pr intArray ( z ) ;

}

/∗∗∗ Methode d i e van twee ar rays van i n t e g e r s enke l de

dubbels t e r u g g e e f t∗ @param in t [ ] x , y∗ @return i n t [ ] dubbel∗/

p r i va t e i n t [ ] dubbel ( i n t [ ] x , i n t [ ] y ){

Page 217: Oplossingen Methodiek van de Informatica

BIJLAGE C. EEN AANTAL INTERESSANTE ALGORITMES 210

// bereken e e r s t het aanta l dubbelsi n t aanta l = 0 ;

f o r ( i n t i =0; i !=x . l ength ; i++){

f o r ( i n t j =0; j !=y . l ength ; j++){

i f ( x [ i ]==y [ j ] ){

aanta l++;}

}}

// ze t de dubbels dan in een aparte arrayi n t [ ] dubbel = new in t [ aanta l ] ;

i n t k=0;

whi l e ( k!= aanta l ){

f o r ( i n t i =0; i !=x . l ength ; i++){

f o r ( i n t j =0; j !=y . l ength ; j++){

i f ( x [ i ]==y [ j ] ){

dubbel [ k ] = x [ i ] ;k++;

}}

}}re turn dubbel ;

}

/∗∗∗ pr in t dubbel∗/

p r i va t e void printDubbel ( i n t [ ] x , i n t [ ] y ){

i n t [ ] z = dubbel (x , y ) ;

pr intArray ( z ) ;}

/∗∗∗ Methode d i e van twee geordende ar rays enke l de

dubbels t e r u g g e e f t∗ @param in t [ ] x , y

Page 218: Oplossingen Methodiek van de Informatica

BIJLAGE C. EEN AANTAL INTERESSANTE ALGORITMES 211

∗ @return i n t [ ] dubbel∗/

p r i va t e i n t [ ] dubbelBis ( i n t [ ] x , i n t [ ] y ){

// bereken e e r s t het aanta l dubbels ( b i n a i rzoeken )

i n t aanta l = 0 ;

f o r ( i n t i =0; i !=x . l ength ; i++){

i f ( b ina i rZoeken (y , x [ i ] ) ){

aanta l++;}

}

// k i j k nu waar de dubbels z i t t e n en ze t deze ineen aparte r i j

// b i n a i r zoekeni n t [ ] dubbel = new in t [ aanta l ] ;

i n t k=0;

whi l e ( k!= aanta l ){

f o r ( i n t i =0; i !=x . l ength ; i++){

i f ( b ina i rZoeken (y , x [ i ] ) ){

dubbel [ k]=x [ i ] ;k++;

}}

}

re turn dubbel ;}

/∗∗∗ Methode om dubbelBis a f te pr in ten∗ @param in t [ ] x , y∗/

p r i va t e void pr intDubbelBis ( i n t [ ] x , i n t [ ] y ){

i n t [ ] z = dubbelBis (x , y ) ;

pr intArray ( z ) ;}

/∗∗

Page 219: Oplossingen Methodiek van de Informatica

BIJLAGE C. EEN AANTAL INTERESSANTE ALGORITMES 212

∗ L inea i r zoeken∗ @param in t zoekwaarde∗ @param in t [ ] r i j∗ @return boolean true / f a l s e∗/

p r i va t e boolean l i n e a i rZo ek en ( i n t [ ] r i j , i n tzoekwaarde )

{boolean inR i j = f a l s e ;

f o r ( i n t i = 0 ; i < r i j . l ength ; i++){

i f ( zoekwaarde == r i j [ i ] ){

i nR i j = true ;}

}re turn inR i j ;

}

/∗∗∗ Bina i r zoeken∗ @param in t zoekwaarde∗ @param in t [ ] r i j∗ @return boolean true / f a l s e∗/

p r i va t e boolean bina i rZoeken ( i n t [ ] r i j , i n tzoekwaarde )

{i n t low = 0 ;i n t high = r i j . length −1;i n t mid ;

whi l e ( low!=high ){

mid = ( low+high ) /2 ;

i f ( zoekwaarde <= r i j [ mid ] ){

high = mid ;}e l s e{

low = mid + 1 ;}

}re turn ( r i j [ low ] == zoekwaarde ) ;

}

/∗∗

Page 220: Oplossingen Methodiek van de Informatica

BIJLAGE C. EEN AANTAL INTERESSANTE ALGORITMES 213

∗ Print de inhoud van een array a f∗ @param in t [ ] eenArray∗/

p r i va t e void pr intArray ( f i n a l i n t [ ] z ){

f o r ( i n t i = 0 ; i !=z . l ength ; i++){

System . out . p r i n t ( z [ i ] + ” ” ) ;}System . out . p r i n t l n ( ) ;

}

}

Page 221: Oplossingen Methodiek van de Informatica

Bijlage D

GNU Free DocumentationLicense

Version 1.2, November 2002Copyright c© 2000,2001,2002 Free Software Foundation, Inc.

51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Everyone is permitted to copy and distribute verbatim copies of this licensedocument, but changing it is not allowed.

Preamble

The purpose of this License is to make a manual, textbook, or other func-tional and useful document “free” in the sense of freedom: to assure everyonethe effective freedom to copy and redistribute it, with or without modifying it,either commercially or noncommercially. Secondarily, this License preserves forthe author and publisher a way to get credit for their work, while not beingconsidered responsible for modifications made by others.

This License is a kind of “copyleft”, which means that derivative works of thedocument must themselves be free in the same sense. It complements the GNUGeneral Public License, which is a copyleft license designed for free software.

We have designed this License in order to use it for manuals for free software,because free software needs free documentation: a free program should comewith manuals providing the same freedoms that the software does. But thisLicense is not limited to software manuals; it can be used for any textual work,regardless of subject matter or whether it is published as a printed book. Werecommend this License principally for works whose purpose is instruction orreference.

1. APPLICABILITY AND DEFINITIONS

This License applies to any manual or other work, in any medium, thatcontains a notice placed by the copyright holder saying it can be distributedunder the terms of this License. Such a notice grants a world-wide, royalty-freelicense, unlimited in duration, to use that work under the conditions stated

214

Page 222: Oplossingen Methodiek van de Informatica

BIJLAGE D. GNU FREE DOCUMENTATION LICENSE 215

herein. The “Document”, below, refers to any such manual or work. Anymember of the public is a licensee, and is addressed as “you”. You accept thelicense if you copy, modify or distribute the work in a way requiring permissionunder copyright law.

A “Modified Version” of the Document means any work containing theDocument or a portion of it, either copied verbatim, or with modificationsand/or translated into another language.

A “Secondary Section” is a named appendix or a front-matter sectionof the Document that deals exclusively with the relationship of the publishersor authors of the Document to the Document’s overall subject (or to relatedmatters) and contains nothing that could fall directly within that overall subject.(Thus, if the Document is in part a textbook of mathematics, a SecondarySection may not explain any mathematics.) The relationship could be a matterof historical connection with the subject or with related matters, or of legal,commercial, philosophical, ethical or political position regarding them.

The “Invariant Sections” are certain Secondary Sections whose titles aredesignated, as being those of Invariant Sections, in the notice that says thatthe Document is released under this License. If a section does not fit the abovedefinition of Secondary then it is not allowed to be designated as Invariant.The Document may contain zero Invariant Sections. If the Document does notidentify any Invariant Sections then there are none.

The “Cover Texts” are certain short passages of text that are listed, asFront-Cover Texts or Back-Cover Texts, in the notice that says that the Doc-ument is released under this License. A Front-Cover Text may be at most 5words, and a Back-Cover Text may be at most 25 words.

A “Transparent” copy of the Document means a machine-readable copy,represented in a format whose specification is available to the general public,that is suitable for revising the document straightforwardly with generic texteditors or (for images composed of pixels) generic paint programs or (for draw-ings) some widely available drawing editor, and that is suitable for input totext formatters or for automatic translation to a variety of formats suitable forinput to text formatters. A copy made in an otherwise Transparent file formatwhose markup, or absence of markup, has been arranged to thwart or discour-age subsequent modification by readers is not Transparent. An image format isnot Transparent if used for any substantial amount of text. A copy that is not“Transparent” is called “Opaque”.

Examples of suitable formats for Transparent copies include plain ASCIIwithout markup, Texinfo input format, LaTeX input format, SGML or XML us-ing a publicly available DTD, and standard-conforming simple HTML, PostScriptor PDF designed for human modification. Examples of transparent image for-mats include PNG, XCF and JPG. Opaque formats include proprietary formatsthat can be read and edited only by proprietary word processors, SGML orXML for which the DTD and/or processing tools are not generally available,and the machine-generated HTML, PostScript or PDF produced by some wordprocessors for output purposes only.

The “Title Page” means, for a printed book, the title page itself, plus suchfollowing pages as are needed to hold, legibly, the material this License requiresto appear in the title page. For works in formats which do not have any titlepage as such, “Title Page” means the text near the most prominent appearanceof the work’s title, preceding the beginning of the body of the text.

Page 223: Oplossingen Methodiek van de Informatica

BIJLAGE D. GNU FREE DOCUMENTATION LICENSE 216

A section “Entitled XYZ” means a named subunit of the Document whosetitle either is precisely XYZ or contains XYZ in parentheses following textthat translates XYZ in another language. (Here XYZ stands for a specific sec-tion name mentioned below, such as “Acknowledgements”, “Dedications”,“Endorsements”, or “History”.) To “Preserve the Title” of such a sec-tion when you modify the Document means that it remains a section “EntitledXYZ” according to this definition.

The Document may include Warranty Disclaimers next to the notice whichstates that this License applies to the Document. These Warranty Disclaimersare considered to be included by reference in this License, but only as regardsdisclaiming warranties: any other implication that these Warranty Disclaimersmay have is void and has no effect on the meaning of this License.

2. VERBATIM COPYING

You may copy and distribute the Document in any medium, either commer-cially or noncommercially, provided that this License, the copyright notices, andthe license notice saying this License applies to the Document are reproducedin all copies, and that you add no other conditions whatsoever to those of thisLicense. You may not use technical measures to obstruct or control the readingor further copying of the copies you make or distribute. However, you mayaccept compensation in exchange for copies. If you distribute a large enoughnumber of copies you must also follow the conditions in section 3.

You may also lend copies, under the same conditions stated above, and youmay publicly display copies.

3. COPYING IN QUANTITY

If you publish printed copies (or copies in media that commonly have printedcovers) of the Document, numbering more than 100, and the Document’s licensenotice requires Cover Texts, you must enclose the copies in covers that carry,clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover,and Back-Cover Texts on the back cover. Both covers must also clearly andlegibly identify you as the publisher of these copies. The front cover mustpresent the full title with all words of the title equally prominent and visible.You may add other material on the covers in addition. Copying with changeslimited to the covers, as long as they preserve the title of the Document andsatisfy these conditions, can be treated as verbatim copying in other respects.

If the required texts for either cover are too voluminous to fit legibly, youshould put the first ones listed (as many as fit reasonably) on the actual cover,and continue the rest onto adjacent pages.

If you publish or distribute Opaque copies of the Document numbering morethan 100, you must either include a machine-readable Transparent copy alongwith each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access todownload using public-standard network protocols a complete Transparent copyof the Document, free of added material. If you use the latter option, you musttake reasonably prudent steps, when you begin distribution of Opaque copiesin quantity, to ensure that this Transparent copy will remain thus accessible atthe stated location until at least one year after the last time you distribute an

Page 224: Oplossingen Methodiek van de Informatica

BIJLAGE D. GNU FREE DOCUMENTATION LICENSE 217

Opaque copy (directly or through your agents or retailers) of that edition to thepublic.

It is requested, but not required, that you contact the authors of the Doc-ument well before redistributing any large number of copies, to give them achance to provide you with an updated version of the Document.

4. MODIFICATIONS

You may copy and distribute a Modified Version of the Document under theconditions of sections 2 and 3 above, provided that you release the ModifiedVersion under precisely this License, with the Modified Version filling the roleof the Document, thus licensing distribution and modification of the ModifiedVersion to whoever possesses a copy of it. In addition, you must do these thingsin the Modified Version:

A. Use in the Title Page (and on the covers, if any) a title distinct from thatof the Document, and from those of previous versions (which should, ifthere were any, be listed in the History section of the Document). Youmay use the same title as a previous version if the original publisher ofthat version gives permission.

B. List on the Title Page, as authors, one or more persons or entities respon-sible for authorship of the modifications in the Modified Version, togetherwith at least five of the principal authors of the Document (all of its prin-cipal authors, if it has fewer than five), unless they release you from thisrequirement.

C. State on the Title page the name of the publisher of the Modified Version,as the publisher.

D. Preserve all the copyright notices of the Document.

E. Add an appropriate copyright notice for your modifications adjacent tothe other copyright notices.

F. Include, immediately after the copyright notices, a license notice givingthe public permission to use the Modified Version under the terms of thisLicense, in the form shown in the Addendum below.

G. Preserve in that license notice the full lists of Invariant Sections and re-quired Cover Texts given in the Document’s license notice.

H. Include an unaltered copy of this License.

I. Preserve the section Entitled “History”, Preserve its Title, and add to itan item stating at least the title, year, new authors, and publisher of theModified Version as given on the Title Page. If there is no section Entitled“History” in the Document, create one stating the title, year, authors, andpublisher of the Document as given on its Title Page, then add an itemdescribing the Modified Version as stated in the previous sentence.

Page 225: Oplossingen Methodiek van de Informatica

BIJLAGE D. GNU FREE DOCUMENTATION LICENSE 218

J. Preserve the network location, if any, given in the Document for publicaccess to a Transparent copy of the Document, and likewise the networklocations given in the Document for previous versions it was based on.These may be placed in the “History” section. You may omit a networklocation for a work that was published at least four years before the Doc-ument itself, or if the original publisher of the version it refers to givespermission.

K. For any section Entitled “Acknowledgements” or “Dedications”, Preservethe Title of the section, and preserve in the section all the substance andtone of each of the contributor acknowledgements and/or dedications giventherein.

L. Preserve all the Invariant Sections of the Document, unaltered in their textand in their titles. Section numbers or the equivalent are not consideredpart of the section titles.

M. Delete any section Entitled “Endorsements”. Such a section may not beincluded in the Modified Version.

N. Do not retitle any existing section to be Entitled “Endorsements” or toconflict in title with any Invariant Section.

O. Preserve any Warranty Disclaimers.

If the Modified Version includes new front-matter sections or appendicesthat qualify as Secondary Sections and contain no material copied from theDocument, you may at your option designate some or all of these sections asinvariant. To do this, add their titles to the list of Invariant Sections in theModified Version’s license notice. These titles must be distinct from any othersection titles.

You may add a section Entitled “Endorsements”, provided it contains noth-ing but endorsements of your Modified Version by various parties–for example,statements of peer review or that the text has been approved by an organizationas the authoritative definition of a standard.

You may add a passage of up to five words as a Front-Cover Text, and apassage of up to 25 words as a Back-Cover Text, to the end of the list of CoverTexts in the Modified Version. Only one passage of Front-Cover Text and oneof Back-Cover Text may be added by (or through arrangements made by) anyone entity. If the Document already includes a cover text for the same cover,previously added by you or by arrangement made by the same entity you areacting on behalf of, you may not add another; but you may replace the old one,on explicit permission from the previous publisher that added the old one.

The author(s) and publisher(s) of the Document do not by this License givepermission to use their names for publicity for or to assert or imply endorsementof any Modified Version.

5. COMBINING DOCUMENTS

You may combine the Document with other documents released under thisLicense, under the terms defined in section 4 above for modified versions, pro-vided that you include in the combination all of the Invariant Sections of all

Page 226: Oplossingen Methodiek van de Informatica

BIJLAGE D. GNU FREE DOCUMENTATION LICENSE 219

of the original documents, unmodified, and list them all as Invariant Sectionsof your combined work in its license notice, and that you preserve all theirWarranty Disclaimers.

The combined work need only contain one copy of this License, and multipleidentical Invariant Sections may be replaced with a single copy. If there aremultiple Invariant Sections with the same name but different contents, makethe title of each such section unique by adding at the end of it, in parentheses,the name of the original author or publisher of that section if known, or else aunique number. Make the same adjustment to the section titles in the list ofInvariant Sections in the license notice of the combined work.

In the combination, you must combine any sections Entitled “History” inthe various original documents, forming one section Entitled “History”; likewisecombine any sections Entitled “Acknowledgements”, and any sections Entitled“Dedications”. You must delete all sections Entitled “Endorsements”.

6. COLLECTIONS OF DOCUMENTS

You may make a collection consisting of the Document and other documentsreleased under this License, and replace the individual copies of this License inthe various documents with a single copy that is included in the collection,provided that you follow the rules of this License for verbatim copying of eachof the documents in all other respects.

You may extract a single document from such a collection, and distribute itindividually under this License, provided you insert a copy of this License intothe extracted document, and follow this License in all other respects regardingverbatim copying of that document.

7. AGGREGATION WITH INDEPENDENTWORKS

A compilation of the Document or its derivatives with other separate andindependent documents or works, in or on a volume of a storage or distributionmedium, is called an “aggregate” if the copyright resulting from the compilationis not used to limit the legal rights of the compilation’s users beyond what theindividual works permit. When the Document is included in an aggregate,this License does not apply to the other works in the aggregate which are notthemselves derivative works of the Document.

If the Cover Text requirement of section 3 is applicable to these copies of theDocument, then if the Document is less than one half of the entire aggregate, theDocument’s Cover Texts may be placed on covers that bracket the Documentwithin the aggregate, or the electronic equivalent of covers if the Document isin electronic form. Otherwise they must appear on printed covers that bracketthe whole aggregate.

8. TRANSLATION

Translation is considered a kind of modification, so you may distribute trans-lations of the Document under the terms of section 4. Replacing Invariant Sec-tions with translations requires special permission from their copyright holders,

Page 227: Oplossingen Methodiek van de Informatica

BIJLAGE D. GNU FREE DOCUMENTATION LICENSE 220

but you may include translations of some or all Invariant Sections in addition tothe original versions of these Invariant Sections. You may include a translationof this License, and all the license notices in the Document, and any WarrantyDisclaimers, provided that you also include the original English version of thisLicense and the original versions of those notices and disclaimers. In case of adisagreement between the translation and the original version of this License ora notice or disclaimer, the original version will prevail.

If a section in the Document is Entitled “Acknowledgements”, “Dedica-tions”, or “History”, the requirement (section 4) to Preserve its Title (section 1)will typically require changing the actual title.

9. TERMINATION

You may not copy, modify, sublicense, or distribute the Document except asexpressly provided for under this License. Any other attempt to copy, modify,sublicense or distribute the Document is void, and will automatically terminateyour rights under this License. However, parties who have received copies, orrights, from you under this License will not have their licenses terminated solong as such parties remain in full compliance.

10. FUTURE REVISIONS OF THIS LICENSE

The Free Software Foundation may publish new, revised versions of theGNU Free Documentation License from time to time. Such new versions will besimilar in spirit to the present version, but may differ in detail to address newproblems or concerns. See http://www.gnu.org/copyleft/.

Each version of the License is given a distinguishing version number. Ifthe Document specifies that a particular numbered version of this License “orany later version” applies to it, you have the option of following the terms andconditions either of that specified version or of any later version that has beenpublished (not as a draft) by the Free Software Foundation. If the Documentdoes not specify a version number of this License, you may choose any versionever published (not as a draft) by the Free Software Foundation.

Page 228: Oplossingen Methodiek van de Informatica

Bibliografie

[1] Model-View-Controller-model. Apr. 2006. http://nl.wikipedia.org/wiki/Model-View-Controller-model.

[2] Jeroen Baert. oefeningen uit Objects First With Java.

[3] Michael Kolling David J. Barnes. Programmeren in JAVA met BlueJ. Pear-son Education Inc., second edition, 2005. http://www.bluej.org.

[4] C. Tomas Wu. An Introduction to Object-Oriented Programming with Java.McGraw-Hill, 2004. Handboek academiejaar 2004-2005.

221