Tentamen Inleiding Programmeren in Java Vakcode: 2lI0L7 Datum: 4 februari 2005 Tijd: 13.30-17.00 uur Algemeen: Dit tentamen bestaat uit 4 opgaven, waarvoor in totaal 100 punten verdiend kunnen worden. De eerste 10 punten zijn gratis.. Blj dit tentamen mag uitsluitend een handbeschreven vel A4 als materiaal gebruikt worden. Opgave í (6 punten) Geef bij elk van de volgende uitspraken aan of ze welof niet wala. zijn: 1. Als a een boolean variabele is, dan leveren de uitdrukkingen "!a" en "a!= false" altijd dezelfde waarde op. 2. Een lokale variabele van een methode kan ook buiten die methode gebruikt worden. 3. Een public ffual attribuut kan buiten de klasse waarin het gedeclareerd is geen nieuwe waarde toegewezen krijgen, maar binnen de klasse wel. 4. Een objectmethode kan geen gebruik maken van klassenattributen. 5. Een klassenmethode kan geen gebruik maken van objectattributen. 6- Als een (formele) parameter van een methode binnen de body een nieuwe waarde toegewezen krijgt, verandert de overeenkomstige (actuele) parameter niet.
Opgave 2 (45 punten) Eind april wordt voor de 33" keer de Batavierenrace gehouden. De afstand van deze estafetteloop is ruim i75 kilometer en is onderverdeeld in 25 etappes. Een eenvoudig (deel)model van deze estafette is gegeven onderstaand klassendiagram. Etappe +int AANTALETAPPES = 25 +int RECORDTïJD = 10000 -int -double etappenummer etappelengte 4 + + J -inl- rannrriti e v v s \ irle +Etappe(int nr, double lengte) +int get,etappenr ( ) +void setrecordtijd( int nieuwetij d) Loper -String naam -Team team -Etappe etappe -int looplijd +Loper(String nm, Team tm, ELappe et) +Etappe getetappe ( ) +inl getlooptijd( ) Team -String naamteam -Loper [ ] deelnemers +Team(String nm) +boolean iscompleet ( ) +void voeglopertoe(loper loper)
De constructor van de klasse Etappe zorgt er voor dat de attributen etappenummer en etappelengte van een beginwaarde woraen voórzien. De recordtijd van de nieuwe instantie is aanvankelijke I 0000 (de constante REcoRDT ï JD). De methode getetappenr geeft het nummer van de etappe en de methode setrecordtijd past de recordti3d uun ut* een ljper de etappe sneller heeft afgelegd dan de huidige recordtijd. 2a (10 pnt) Geef de code van de klasse Etappe. De constructor van de klasse Loper zorgt naast initialisatie van de attributen er ook voor dat deze loper aan het betreffende team wordt toegevoegd (zie de klasse Team). De methode getetappe levert de etappe van deze loper op en de áethoáe get.loopti j d geeft de-looptijd van deze_loper' De looptijd is^initieel nul enïan worden geset met de later te maken methode setloopti j d. 2b (8 pnt) Geef de code van de klasse Loper. De klasse Loper is nog voorzien van de volgende methoden: *levert de loopsnelheid (in km/u) op van deze loper of 0 als er *nog geen tijd bekend is. public double getloopsnelheid ( ) { *de gelopen tijd van deze loper wordt gezet en eventueel wordt de *recordtijd van de gelopen etappe aangepast' *@param lt.ijd de gelopen tijd x/ public void setlooptijd(in ltijd) { i 2c (6 pnt) Schrijf de implementatie van bovenstaande methoden. Een team van lopers heeft een naírm en bestaat uit zoveel lopers als er etappes zijn. De klasse Team heeft dus een naam en een aíray van lopers als attribuut. In de constructor worden deze attributen op de juiste waarde geinitialiseerd. De methode iscompleet onderzoekt of er voor elke etappe een loper is. De methode voeglopertoe zet, indien het team nog niet compleet is, de loper op de juiste plaats in de array deelnemers. 2d (3pnt) 2e (8 pnt) 2f (10 pnt) Geef de implementatie van de contructor Team. Geef de specificatie en implementatie van de methode iscompleet. Geef de specificatie en implementatie van de methode voegloperlfoe.
- Opgave 3 (12 Punten) Beschouw nu het volgende prograínmafragment: L Team Leaml= new Team('Teama') ; 2 Etappe etl- = new EtaPPe (1",3-2) ; 3 Etappe el2 = new EtaPPe (2,7.0) i 4 EtapPe et3 = new EtaPPe (3, 1-1- - 9 ) ; r 6 Loper henny = new Loper('Henny'' teaml-' et1) ; 7 Loper karel = new Loper('Karel',teaml-,et3); a 9 teaml.voeglopertoe(henny) ; l-0 teaml-. voeglopertoe (karel ) ; 1-1 t2 henny. setloopttijd(708) ; l-3 karel. setï,ooptijd(2503) ; 3a (4 pnt) Teken het geheugenmodel (objectdiagram) na regel 4' 3b (3 pnt) 3c (1 pnt) Geef de aanpassing/uitbreiding na de regels 6"10' Geef de aanpassingluitbreiding na de regels 12 en 13. :d (4 pnq Wat is na afloop van bovenstaand prografirmafragment de waarde/resultaat van de onderstaande uitdrukkingen. Indien eeï uitdrukking niet correct kan worden uitgevoerd geef dan aan wat de fout is. 20 henny.getnaam0 == 'HennY'; )1 hennrr. team == teaml-; 22 et2 == karel.getetappe0; 23 karel.serlooptijd(et2.setrecordtijd(2500) ) ; 24 et3. etappelengte = 3.3;
Apgave 4 (27 punten) Gegeven zijn onderstaande twee klassen, Bestand Gegevens.java 1 2 publíc claes Gegevens 1 { i / /Lengte array 6 7 8 9 public Gegevenso { this"info = nêw GegevenlGegevens.aRL];] public void initgegevens ( ) tl 12 public void grapjeo 13 {for (ffi; tel< Gegevens.ARL;te1=te1+2) this. info Ite]-l. initnaam( ) ; ] t4 15 public int 16 //nog meer n 18 public inè 19 //nog meer 2 0 ) Bestand Gegeven.iava 2l 22 public clasg Gegeven ffi-w(strins woord) { /"ffiffi*m "/ methoden die operatie op de data mogelijk maken ffioiz*ffi*ui methoden die operatie op de data mogelijk maken 25 26 27 28 29 30 31 32 JJ 34 35 36 37 38 39 40 4l public Gegeveno {; public void initnaamo {this.naam=ílew String( public String getnaamo {return this.naam; " " ) ; public void setnaam (String naam) {this.naam=naam ; public int getvolgnummer ( ) { return ttris.volgnummer ; public void setvolgnummer tint ffi) i this. volgnummer=nummer ) ; ) De grijze markering is ten behoeve van opgave 4c en heeít verder geen betekenis. Beschouw nu het volgende programmafragment: private Gegevens inf; inf=new Gegevens O ; inf. inilgegevens O ; ;-c ^-^*l^ / \. Irr!,u!q/Js\r,,// situatie A,// situatie e //situatie C //siluatie D
4a (5 pnt) GeeÍ de bij de situatie A, B, C en D behorende geheugenmodel (objectdiagram). Duidelijk moet zijn of een variabele een waarde heeft, een NULL reíerentie (x) heeít of ongedeíinieerd is (?). fn klasse Gegeven wordt in de methoden seërvaam en setvofgnuírnner het sleutelwoord this gebruikt. 4b (2 pnt) Vertel wat dit betekent en leg uit wat het eífect van deze methoden zou ziin als de beide this's daar niet zouden staan. Gegeven de volgende veel gebruikte begrippen. Y. h.l_. l. Klasse attribuut Object altribuut Lokale variabele Formel-e (paramet,er) Actuele (parameter) Terugkeerwaarde Variabele declaralie Object creatie PrÍmitief (type) Ref erenlie (tlpe) k. 'l m. o, q. r, t. Methode heading Methode body Klasse Instantie van een klasse Obj ect. ConsLructor "maakt gebruik van" " j-s een uitbreiding (overerving) ToekenningsopdrachL ( associatie ) van" 4c (10 pnt) Vul op de plaatsen mel <<begrip?>> een begrip uit de bovenstaande lijst in (totaal 12 begrippen). fn de klasse Gegevenwordt in regel23 een << begrip />> van het << begrip 2>> (type) gedeclareerd. ln regel24 wordt een declaratie gecombineerd met << begrip 3>> aan de waarde 0' De kfasse Gegevens heeít een << begrip 4>> relatie met de klasse Gegeveni dit is te zien in regel 5. Hier wordthel << begrip 5>> inf o van het << begrip ó>> (type) gedeclareerd. fn regef 10 vindt de << begrip 7>> van de elementen van het array plaats. De << begrip 8>> Ëet is van het << begrip 9>> (type) en wordt ook wel de lopende'oí indexvariabele genoemd. ln regel 4 wordt het << begrip I0>> ARL gedeclareerd. Omdat ARL binnen zijn eigen klasse gebruikt wordt zou in regel I ook Ian-c I of [this.arl] mogen staan. Neem de methode die begint in regel 40 in beschouwing, nunrmer in regel 40 is een << begrip 11>> en is een onderdeel van << begrip I2>> 6
Bij de opgaven d, e en f mag de herhalingsopdracht niet worden afgebroken met een return of break. Bij opgave e en Í mag je aannemen dat de methode initcevens uitgevoerd is 4d(4pnt) Transformeer het Íor-statement uit rnjtgegevens (regel 9) naar een while'statement. Ondersteun je ontwerp met een schets van het array, geef in deze schets duidelijk de rol van tel (ook wel lopende variabele genoemd) aan, beschrijí de betekenis van deze variabele en motiveer de startwaarden stopconditie. De methode tefngllstrings levert het aantal keren dat naam in het array de waarde NULL heeft' 4e (3 pnt) lmplementeer de methode public int telnur,r,strings O (regel 18). Je heb de keuze om deze opgave op te lossen met een for-statement of een while-statement. Motiveer jouw keuze (geen gebruik van relurn of break!). De methodê zoekwoord levert het volgnummer op van de laatste keer dat woord in het array Lhis.:.nfo VooÍkomt, dit gerekend vanaf index 0. 4f (3pnt) lmplementeer de methode public int zoekwoord (SLring woord).(regel 15) Je heb de keuze om deze opgave op te lossen met een for-statement of een whilestatement. Motiveer jouw keuze (geen gebruik van return of break!). Met welke terugkeerwaarde(n) kan er aangeven worden dal woord niet voorkomt?
Opgave 1 1. Niet waar. Als a waar is, levert!a nietwaar op, maar a!= false levert waar op. 2. Niet waar. Een lokale variabele van een methode is alleen beschikbaar binnen de methode. 3. Waar. Er kan 1 keer een waarde toegekend worden aan een final attribuut, dat kan bij het declareren van het attribuut of in de constructor van de klasse (1 keer!). Dus alleen binnen de klasse, en slechts 1 keer. 4. Nietwaar. Iedereen kan gebruik maken van klassenattributen (als ze public zijn), dus ook de objectmethoden van die klasse. 5. Waar Een klassemethode kan geen gebruik maken van de objectattributen van een object van die klasse, omdat de methode aangeroepen kan worden voordat er een object aangemaakt is. Wel kan de methode een object aanmaken of meekrijgen als parameter en de objectattributen van dat object benaderen (als ze public zijn). 6. Waar De formele parameter is een kopie van de actuele parameter. In het geval van een primitieve dus een kopie van de waarde, in het geval van een object een kopie van de verwijzing. Wanneer dus de waarde van de formele parameter zelf veranderd wordt, wordt de waarde van de kopie veranderd: de waarde van de primitieve wordt veranderd of de verwijzing naar het object. Wordt echter iets veranderd aan het object waar de formele parameter naar verwijst, is dit een verandering aan het object waar ook de actuele parameter heen wijst. Opgave 2 a. * De klasse etappe beschrijft een etappe van de Batavierenrace * Het etappenummer, de etappelengte en de recordtijd wordt bijgehouden * @author Albert Molderink * @version 1.0 public class Etappe{ public static final int AANTALETAPPES = 25; public static final int RECORDTIJD = 10000; private int etappenummer; private double etappelengte; private int recordtijd; * Constructor voor de klasse Etappe * Het etappenummer en de lengte worden gezet op de waarden van de parameters, * als de waarde van de parameters geldig zijn. De recordtijd wordt op een * waarde van 10000 geinitieerd (RECORDTIJD) * @param nr het nummer van de etappe, moet liggen tussen 1 en AANTALETAPPES * @param lengte de lengte van de etappe, moet groter dan 0 zijn public Etappe(int nr, double lengte){ if(nr<=etappe.aantaletappes){ //klopt het etappenummer wel? this.etappenummer=nr;
else{ etappenummer=-1; if(lengte>0){ this.etappelengte=lengte; else{ this.etappelengte=0; this.recordtijd = Etappe.RECORDTIJD; * Geeft het nummer van de etappe * @return het nummer van de etappe public int getetappenr(){ return etappenummer; * Zet de recordtijd op de waarde van de parameter, als dit tenminste echt een * nieuwe recordtijd is, anders blijft de oude waarde staan * @param nieuwetijd de nieuwe recordtijd, moet groter dan 0 zijn public void setrecordtijd(int nieuwetijd){ if(nieuwetijd<this.recordtijd){ this.recordtijd=nieuwetijd; b. * Klasse die een loper van de batavierenrace beschrijft * @author Albert Molderink * @version 1.0 public class Loper{ private String naam; private Team team; private Etappe etappe; private int looptijd; * Constructor voor de klasse Loper. De naam, het team en de etappe worden * gezet op de waarden van de parameters, de looptijd wordt op 0 gezet. Verder * wordt de loper toegevoegd aan het team. * @param nm de naam van de speler * @param tm het team waarin de loper loopt * @param et de etappe die de loper loopt public Loper(String nm, Team tm, Etappe et){ this.naam=nm; this.team=tm; this.etappe=et; this.looptijd=0; team.voeglopertoe(this); //this geeft het huidige object
* Geeft de etappe die de loper loopt * @return de etappe waarin de loper loopt public Etappe getetappe(){ return this.etappe; * Geeft de tijd die de loper nodig had voor de etappe * @return de tijd die de loper nodig had de etappe te lopen public int getlooptijd(){ return this.looptijd; c. * Geeft de gemiddelde snelheid die de loper gelopen heeft tijdens de etappe * @return de gemiddelde snelheid tijdens de etappe public double getloopsnelheid(){ if(this.looptijd==0){ return 0; else{ double afstand = et.getetappelengte(); //we gaan er vanuit dat deze //methode bestaat return this.looptijd/afstand; * Zet de tijd die de loper nodig had voor de etappe, zo nodig wordt ook de * recordtijd van de etappe aangepast * @param ltijd de tijd die de loper nodig had voor de etappe, moet groter dan 0 * zijn public void setlooptijd(int ltijd){ this.looptijd=ltijd; et.setrecordtijd(ltijd); //deze methode controleert of het wel echt een //recordtijd is d. * Constructor voor de klasse Team, het aantal lopers wordt geinitieerd op 0 * @param nm de naam van het team public Team(String nm){ this.naam=nm; this.lopers = new Loper[Etappe.AANTALETAPPES]; this.aantallopers=0;
e. * Methode die controleert of er even veel lopers zijn bij een team als er etappes * zijn * @return een boolean of er evenveel lopers als etappes zijn public boolean iscompleet(){ return (this.aantallopers==etappe.aantaletappes); f. * Voeg een loper toe aan het team * @param lp de loper die toegevoegd moet worden aan het team public void voeglopertoe(loper lp){ if(this.aantallopers<etappe.aantaletappes){ this.lopers[aantallopers]=lp; this.aantallopers++; Opgave 3 (klassenattributen en methoden mogen onderstreept aangegeven worden in het object diagram, een array is aangegeven als een object met schuingedrukt de lengte) a team1: Team naamteam : deelnemers : aantallopers : 0 naamteam: String Teama deelnemers : Array lengte 25 et1 : Etappe et2 : Etappe et3 : Etappe AANTALETAPPES : 25 RECORDTIJD : 10000 etappenummer : 1 etappelengte : 3.2 recordtijd : 10000 AANTALETAPPES : 25 RECORDTIJD : 10000 etappenummer : 2 tappelengte : 7.0 recordtijd : 10000 AANTALETAPPES : 25 RECORDTIJD : 10000 etappenummer : 3 etappelengte : 11.9 recordtijd : 10000
b Er worden twee lopers aangemaakt en toegevoegd aan de array. Alleen de array en de lopers zijn getekend. We gaan er even vanuit dat de lopers maar een keer toegevoegd worden (niet en in de constructor zoals in de vorige opdracht en regel 9-10). Wil je dit wel meenemen, komen er twee pijlen vanuit de array naar ieder object. team1: Team naamteam : deelnemers : aantallopers : 2 naamteam: String Teama deelnemers : Array lengte 25 naam: String Henny henny : Loper naam : team : etappe : looptijd : 0 karel : Loper naam : team : etappe : looptijd : 0 naam : String Karel et1 : Etappe et2 : Etappe et3 : Etappe AANTALETAPPES : 25 AANTALETAPPES : 25 AANTALETAPPES : 25 RECORDTIJD : 10000 RECORDTIJD : 10000 RECORDTIJD : 10000 etappenummer : 1 etappenummer : 2 etappenummer : 3 etappelengte : 3.2 tappelengte : 7.0 etappelengte : 11.9 recordtijd : 10000 recordtijd : 10000 recordtijd : 10000 c De looptijd van de lopers wordt aangepast en daarom ook de recordtijd van de etappes als dat nodig is. team1: Team naamteam : deelnemers : aantallopers : 2 naamteam: String Teama deelnemers : Array lengte 25 naam: String Henny henny : Loper naam : team : etappe : looptijd : 708 karel : Loper naam : team : etappe : looptijd : 2503 naam : String Karel et1 : Etappe et2 : Etappe et3 : Etappe AANTALETAPPES : 25 AANTALETAPPES : 25 AANTALETAPPES : 25 RECORDTIJD : 10000 RECORDTIJD : 10000 RECORDTIJD : 10000 etappenummer : 1 etappenummer : 2 etappenummer : 3 etappelengte : 3.2 tappelengte : 7.0 etappelengte : 11.9 recordtijd : 708 recordtijd : 10000 recordtijd : 2503
d 20. NIETWAAR: twee objecten kunnen op deze manier niet vergeleken worden, op deze manier worden twee verwijzingen vergeleken. 21. FOUTMELDING: het attribuut team is private, dus kan niet van buiten het object benadert worden 22. NIETWAAR: ten eerste worden hier ook weer twee verwijzingen vergeleken, maar karel loopt echter etappe 3. De vergelijking et3==karel.getetappe() vergelijkt ook twee verwijzingen, maar dat zijn twee verwijzingen naar hetzelfde object, dus dat zou WAAR opleveren 23. FOUTMELDING: de methode setlooptijd wordt aangeroepen op het object karel, dat is prima. De methode setrecordtijd aanroepen op et2 gaat ook prima, ook een methode aanroep als parameter mee geven gaat goed. De returnwaarde van de binnenste methode wordt dan meegegeven als parameter aan de buitenste methode. Maar de methode setlooptijd heeft een int als parameter, de methode setrecordtijd heeft als returntype void. 24. FOUTMELDING: etappelengte is een private attribuut Opgave 4 a situatie A: er wordt alleen ruimte voor de verwijzing naar het object gemaakt. situatie B: er wordt ook geheugen gereserveerd voor het object: inf : Gegevens ARL : 6 info : info : Array lengte 6 situatie C: er zijn 6 objecten van de klasse Gegeven aangemaakt en toegevoegd aan de array (er zijn er 2 getekend). Volgnummer staat op 0 omdat dit de beginwaarde is, de string naam verwijst nog niet naar een object, alleen de verwijzing is nog maar aangemaakt, nog geen object. inf : Gegevens ARL : 6 info : info : Array lengte 6 gegeven1 : Gegeven naam : x volgnummer : 0 gegeven2 : Gegeven naam : x volgnummer : 0 situatie D: de object in de array info op de plaasten 0, 2 en 4 worden aangepast (tel=tel+2). Bij deze object wordt de String naam geinitieerd op (er zijn weer twee object getekend). inf : Gegevens ARL : 6 info : info : Array lengte 6 naam : String gegeven1 : Gegeven naam : volgnummer : 0 gegeven2 : Gegeven naam : x volgnummer : 0
b Bij setnaam geeft this.naam aan dat de waarde van het objectattribuut verandert moet worden. Omdat er in de methode een variabele naam gedeclareerd wordt, zou zonder this die variabele bedoelt worden. Het zou dus fout gaan zonder this. Bij setvolgnummer geeft this opnieuw aan dat het objectattribuut bedoelt wordt, maar er wordt in de methode geen variabele volgnummer gedeclareerd, dus ook zonder this is het duidelijk dat het attribuut bedoelt wordt. Deze methode zou hetzelfde werken zonder this. c In de klasse Gegeven wordt in regel 23 een Object attribuut van het Referentie (type) gedeclareerd. In regel 24 wordt een declaratie gecombineerd met Toekenningsopdracht aan de waarde 0. De klasse Gegevens heet een maakt gebruik van (associatie) relatie met de klasse Gegeven; dit is te zien in regel 5. Hier wordt het Object attribuut van het Array (type) gedeclareerd. In regel 10 vind de Object creatie van de elementen van het array plaats. De lokale variabele tel is van het primitief (type) en wordt ook wel de lopende- of indexvariabele genoemd. In regel 4 wordt het Klasse attribuut ARL gedeclareerd. Omdat ARL binnen zijn eigen klasse gebruikt wordt zou in regel 8 ook [ARL] of [this.arl] mogen staan. Neem de methode die begint in regel 40 in beschouwing, nummer in regel 40 is een Formele parameter en is een onderdeel van methode heading. d De tel doorloopt iedere index van de array, hij loopt door de array, vandaar lopende variabele. De startwaarde is 0: de waarde van de eerste index. De stopwaarde is het einde van de array, de laatste index is de lengte van de array -1. Dus als tel de lengte van de array bereikt, moet hij stoppen. tel info... int tel=0; while(tel<gegevens.arl){ this.info[tel]=new Gegeven(); tel++; e Ik heb gekozen voor een for-lus omdat ik precies weet hoe vaak het uitgevoerd moet worden, de hele array moet doorgelopen worden. * Telt het aantal keren dat er een object van het type Gegeven in de array zit * waarvan de naam nog niet geinitialiseerd is (NULL) * @return het aantal keren dat er een NULL string voorkomt public int telnullstrings(){ int teller=0; for(int tel=0;tel<gegevens.arl;tel++){ if(this.info[tel].getnaam()==null){ teller++;
return teller; f Ik heb een for-lus gebruikt omdat ik precies weet hoe vaak het uitgevoerd moet worden, namelijk net zo vaak als de array lang is. Als terugkeerwaarde als hij niet gevonden is heb ik -1 gekozen, dat is een ongeldige index van een array en geeft zo aan dat hij er niet in voorkomt. * Deze methode zoek het laatste voorkomen van woord in de verzameling van gegevens * @param woord het woord dat je zoek * @return de laatste index waar het woord voorkomt, anders -1 public int zoekwoord(string woord){ int teller=-1; String temp; for(int tel=0;tel<gegevens.arl;tel++){ temp=this.info[tel].getnaam(); if(temp.equals(woord)){ teller=tel; return teller; Een tweede voorbeeld: met een while lus. Deze implementatie is optimaler dan de vorige: hij begint aan de achterkant van de array te zoeken totdat hij woord tegenkomt. Als woord voorkomt, is deze eerder klaar dan de methode die aan de voorkant begint. De terugkeerwaarde is opnieuw -1 als hij niet gevonden wordt. MERK OP: zie je dat de javadoc voor beide implementatie's gelijk is? Dus dat een gebruiker van de klasse geen verschil tussen de implementatie's ziet, omdat hij alleen de javadoc bekijkt. En dat het voor de gebruiker ook niet uitmaakt, als er maar het goede resultaat uitkomt. * Deze methode zoek het laatste voorkomen van woord in de verzameling van gegevens * @param woord het woord dat je zoek * @return de laatste index waar het woord voorkomt, anders -1 public int zoekwoord(string woord){ bool gevonden = false; int teller = Gegevens.ARL; while( teller > 0 &&!gevonden){ teller--; //eerst verlagen! gevonden=this.info[teller].getnaam().equals(woord); //snap je dit? if(gevonden){ return teller; else{ return -1;