TDT4100 Objektorientert programmering



Like dokumenter
TDT4100 Objektorientert programmering

TDT4100 Objektorientert programmering

TDT4100 Objektorientert programmering

class Book { String title; } class Dictionary extends Book { int wordcount; } class CartoonAlbum extends Book { int stripcount; }

TDT4100 Objektorientert programmering

TDT4100 Objektorientert programmering

Arv. Book book1 = new Book(); book1. title = "Sofies verden" class Book { String title; } class Dictiona ry extends Book {

BOKMÅL Side 1 av 7. KONTINUASJONSEKSAMEN I FAG TDT4100 Objektorientert programmering / IT1104 Programmering, videregående kurs

TDT Prosedyre- og objektorientert programmering

Eksamensoppgave i TDT4100 Objektorientert programmering med Java

Eksamensoppgave i TDT4100 Objektorientert programmering med Java

TDT4100 Objektorientert programmering

Eksamensoppgave i TDT4100 Objektorientert programmering med Java

TDT4100 Objektorientert programmering

EKSAMEN I FAG TDT4100 Objektorientert programmering. Fredag 6. juni 2008 Kl

TDT Prosedyre- og objektorientert programmering

UNIVERSITETET I OSLO

Eksamen Objektorientert Programmering 2013

EKSAMEN I FAG TDT4100 Objekt-orientert programmering. Fredag 3. juni 2005 KL

UNIVERSITETET I OSLO

Læringsmål for forelesningen

Eksamen. Objektorientert Programmering IGR 1372

Repitisjonskurs. Arv, Subklasser og Grensesnitt

UNIVERSITETET I OSLO

Eksekveringsrekkefølgen (del 1) Oppgave 1. Eksekveringsrekkefølgen (del 2) Kommentar til oppgave 1. } // class Bolighus

LO191D/LC191D Videregående programmering

TDT Prosedyre- og objektorientert programmering

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

Eksamen Oppgave a) public class DayTime { public final int hours, minutes;

INF Seminaroppgaver til uke 3

TDT Prosedyre- og objektorientert programmering

UNIVERSITETET I OSLO

Konstruktører. Bruk av konstruktører når vi opererer med "enkle" klasser er ganske ukomplisert. Når vi skriver. skjer følgende:

UNIVERSITETET I OSLO

2 Om statiske variable/konstanter og statiske metoder.

Array&ArrayList Lagring Liste Klasseparametre Arrayliste Testing Lenkelister

1- og 2-veis Innkapsling Java Stabel Kø Prio-kø Iterator. Enveis- og toveislister Innkapsling («boxing») (Big Java 6.8.5)

EKSAMEN I FAG TDT4100 Objektorientert programmering. Fredag 2. juni 2006 Kl

Account. valideringslogikken. Det er vanligst å bruke en såkalt unchecked exception (usjekket unntak), som IllegalArgumentException.

EKSAMENSFORSIDE SKRIFTLIG EKSAMEN

Faglærerne prøver å besøker eksamenslokalet mellom klokka 15 og 16 for å oppklare eventuelle uklarheter og feil i oppgaveteksten.

< T extends Comparable<T> > Indre klasser mm. «Det du bør ha hørt om før oblig 4»

UNIVERSITETET I OSLO

BOKMÅL Side 1 av 5. KONTERINGSEKSAMEN I FAG TDT4102 Prosedyre og objektorientert programmering. Onsdag 6. august 2008 Kl

Kontinuasjonseksamensoppgave i TDT4100 Objektorientert programmering

1- og 2-veis Innkapsling Java Stabel Kø Prio-kø Iterator. Enveis- og toveislister Innkapsling («boxing») (Big Java 6.8.5)

Løsningsforslag ukeoppg. 6: 28. sep - 4. okt (INF Høst 2011)

UNIVERSITETET I OSLO

INF1010 Eksamenstips. Løsningsforslag prøveeksamen del 1.

Fakultet for informasjonsteknologi, Institutt for datateknikk og informasjonsvitenskap

TDT4102 Prosedyre og Objektorientert programmering Vår 2014

Tillatte hjelpemidler: alle skrevne og trykte. Antall sider: 2 (+ 1 side vedlegg, bakerst). Oppgave 1 [25%]

Array&ArrayList Lagring Liste Klasseparametre Arrayliste Testing Lenkelister Videre

Tittel Objektorientert systemutvikling 1. Eksamenstid, fra-til Ant. oppgaver 6

EKSAMEN. Dato: 9. mai 2016 Eksamenstid: 09:00 13:00

Algoritmer og datastrukturer Eksamen

UNIVERSITETET I OSLO

INF 1010, vår 2005 Løsningsforslag uke 11

Kapittel 7: Mer om arv

LC191D/LO191D Videregående programmering mai 2010

Oppsummering. Kort gjennomgang av klasser etc ved å løse halvparten av eksamen Klasser. Datastrukturer. Interface Subklasser Klasseparametre

Læringsmål for forelesningen

. Ved sensur vl1 ahe bokstaverte deloppgaver (a, b, c,...) telle like mye.

Kapittel 8: Programutvikling

Eksamensoppgave i TDT4100 Objektorientert programmering

EKSAMEN. Objektorientert programmering

Objektorientert Programmering Ekstraordinær eksamen 2014

Antall sider (inkl. forsiden): 7. Alle trykte og håndskrevne

Læringsmål for forelesningen

UNIVERSITETET I OSLO

ANTDAGER = 358; I Ifra nyttår 08 til 08 1ed julaften

UNIVERSITETET I OSLO

Innhold uke 7. Objektorientert programmering i Python: Introduksjon. Lite tilbakeblikk: Programflyt og skop. Lite tilbakeblikk: Funksjoner er uttrykk

EKSAMENSOPPGAVE. INF-1100 Innføring i programmering og datamaskiners virkemåte. Ingen. Elektronisk (WiseFlow) Robert Pettersen

UNIVERSITETET I OSLO

Algoritmer og datastrukturer Eksamen

LC191D Videregående programmering Høgskolen i Sør-Trøndelag, Avdeling for informatikk og e-læring. Else Lervik, januar 2012.

INF1000 Metoder. Marit Nybakken 16. februar 2004

UNIVERSITETET I OSLO

INF1010 våren 2008 Uke 4, 22. januar Arv og subklasser

INF Notater. Veronika Heimsbakk 10. juni 2012

Oppgave 1. Sekvenser (20%)

IN1010 V18, Obligatorisk oppgave 5

Algoritmer og datastrukturer Kapittel 3 - Delkapittel 3.1

Algoritmer og datastrukturer Eksamen

OO-eksempel. Modellen ser slik ut: Studenter + antstudenter : int = 0

Eksamensoppgave i TDT4100 Objektorientert programmering

INF1010, 22. mai Prøveeksamen (Eksamen 12. juni 2012) Stein Gjessing Inst. for Informatikk Universitetet i Oslo

Introduksjon til objektorientert. programmering. Hva skjedde ~1967? Lokale (og globale) helter. Grunnkurs i objektorientert.

Løsningsforslag Test 2

Eksamen IN1010/INF1010 våren 2018

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

Oppgavesettet består av 7 sider, inkludert denne forsiden. Kontroll& at oppgaven er komplett før du begynner å besvare spørsmålene.

INF1010 Arv. Marit Nybakken 2. februar 2004

Obligatorisk oppgave 5: Labyrint

UNIVERSITETET I BERGEN Det matematisk-naturvitenskapelige fakultet

Del 3: Evaluere uttrykk

Transkript:

Eksamensoppgave i TDT4100 Objektorientert programmering Lørdag 22. mai 2010, kl. 09:00-13:00 Oppgaven er utarbeidet av faglærer Hallvard Trætteberg og kvalitetssikrer Trond Aalberg. Kontaktperson under eksamen Hallvard Trætteberg (mobil 918 97263) Språkform: Bokmål Tillatte hjelpemidler: C Én valgfri lærebok i Java er tillatt. Bestemt, enkel kalkulator tillatt. Sensurfrist: Mandag 14. juni. Les oppgaveteksten nøye. Finn ut hva det spørres etter i hver oppgave. Dersom du mener at opplysninger mangler i en oppgaveformulering gjør kort rede for de antagelser og forutsetninger som du finner det nødvendig å gjøre. Side 1 av 10

Del 1 Innkapsling (20%) a) Hva er hensikten med innkapsling? Innkapsling skal sikre et objekt starter og forblir i en gyldig tilstand og at innholdet kan leses og endres uten å avdekke den interne representasjonen og implementasjonen. b) Lag en Date-klasse med metoder for å lese og endre informasjon om dag, måned og år, slik at denne informasjonen blir ordentlig innkapslet og validert. Velg selv konstruktør(er) og metoder som inngår i innkapslingen, egnet intern representasjon og evt. interne hjelpemetoder. Du kan anta det finnes en hjelpemetode som sier om et år er et skuddår. Gjør kort rede for dine valg og husk at det finnes flere fullgode løsninger. Det finnes flere fullgode løsninger. Den enkleste (naïve) løsningen er ett int-felt (privat) for hhv. dag, måned og år og get/set-metoder (public) for hver av disse. I hver set-metode bør en validere om endringen vil gi en ugyldig dato, før selve endringen skjer. Denne valideringen er lik for alle setmetodene og bør legges i en egen valideringsmetode (public). Ved feil, bør en bruke en IllegalArgumentException eller RuntimeException, eller en egendefinert subklasse av en av disse. Det er ryddig å ha en egen metode som returnerer antall dager i en måned, gitt året, som kan brukes i valideringsmetoden og i c). Det kan argumenteres for at det er uheldig å teste for gyldighet av hele tilstanden, når tilstanden kan endres bitvis. Da bør det være en begrunnelse, og valideringsmetoden må være public, slik at ekstern kode kan validere selv. Problemstillingen kan unngås ved å velge én set-metode for all informasjonen, slik at hele tilstanden settes (og valideres) på en gang. Vi velger her det første alternativet. public class Date { private int day, month, year; public Date(int day, int month, int year) { check(day, month, year); this.day = day; this.month = month; this.year = year; private boolean isleapyear(int year) { return (year % 4 == 0 && (year % 400 == 0 year % 100!= 0)); private int numberofdays(int month, int year) { switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: return 31; case 4: case 6: case 9: case 11: return 30; case 2: return (isleapyear(year)? 29 : 28); return -1; Side 2 av 10

private void check(int day, int month, int year) { if (day < 1 day > numberofdays(month, year)) { throw new IllegalArgumentException("day is illegal: " + day); if (month < 1 month > 12) { throw new IllegalArgumentException("month is illegal: " + day); public int getday() { return day; public void setday(int day) { check(day, month, year); this.day = day; public int getmonth() { return month; public void setmonth(int month) { check(day, month, year); this.month = month; public int getyear() { return year; public void setyear(int year) { check(day, month, year); this.year = year; c) Implementer metoder for å endre datoen til neste og forrige dag. Merk at disse metodene skal endre Date-objektet selv, ikke lage nye Date-objekter. Det er mest snakk om å holde tunga rett i munnen. public void nextday() { day++; if (day > numberofdays(month, year)) { day = 1; month++; if (month > 12) { month = 1; year++; public void previousday() { day--; if (day < 1) { Side 3 av 10

month--; if (month < 1) { month = 12; year--; day = numberofdays(month, year); Del 2 Typer (10%) Anta følgende klasser, grensesnitt og metoder: - Klasse A deklarerer metoden A methoda(). - Grensesnittet G deklarerer metoden G methodg(a). - Klasse B arver fra A, implementerer G og deklarerer metoden B methodb(a). - Klasse C implementerer G og deklarerer metoden C methodc(g). a) Hvilke av følgende deklarasjoner/initialiseringer vil gi feil i editoren/ved kompilering: A a = new B(); B b = new A(); G g1 = new A(), g2 = new B(), g3 = new C(); Her ble det (dessverre) ikke spurt om noen forklaring, så det er nok å angi hvilke som er feil. B b = new A() er ulovlig, siden en A ikke er en B G g1 = new A()er ulovlig, siden en A ikke implementerer G b) Anta i det følgende at variablene a, b og c er deklarert til å være av klassene A, B og C. Hvilke av følgende uttrykk vil gi feil i editoren/ved kompilering og hvorfor: a.methoda() == c.methodc(a) b.methoda().tostring() b.methodg(new B()) ((G) a).methodg(a) ((B) a).methodg(b) ((C) a).methodg(a) c.methodc(a) er ulovlig, siden en A ikke er en C ((C) a).methodg(a) er ulovlig, siden en A ikke også kan være en C Side 4 av 10

Del 3 Klasser (35%) For å kunne stave ord over en dårlig kommunikasjonslinje er det vanlig å bruke et ord-basert alfabet, hvor første bokstav i ordet tilsvarer bokstaven som sies. Nato har standardisert dette i sitt fonetiske alfabet, som begynner med alfa, bravo, charlie, delta, echo, foxtrot. Dersom ordet java staves med dette alfabetet blir det juliet alfa viktor alfa. Du skal implementere en klasse RadioAlphabet for å konvertere bokstaver og ord vha. denne teknikken. Du velger selv hvordan alfabetet representeres, f.eks. kan en String, String-tabell, List eller Map brukes for å representere alfabetet. Merk at det kan være lurt å lese gjennom hele oppgaven og ta en titt på oppgave 5, før du velger mellom en av disse og evt. andre alternativer. a) Først skal du implementere én konstruktør og to metoder, som følger: - Konstruktøren skal ta inn ordene i alfabetet som en String og en String som inneholder skilletegnet. Merk at ordene trenger ikke være i alfabetisk rekkefølge, fordi første bokstav i ordet avgjør hvilken bokstav det tilsvarer. F.eks. skal new RadioAlphabet( alfa-bravodelta-charlie, - ) gi et objekt som kan oversette bokstavene a - d med Natoalfabetet. Alfabetet skal kun kunne inneholde ord for bokstaver (altså ikke tall og skilletegn). - Metoden String convert(char) skal returnere ordet som tilsvarer bokstaven som gis som parameter, eller null dersom bokstaven ikke kan oversettes. F.eks. skal convert( a ) returnere alfa og convert(! ) skal returnere null. - Metoden String convert(string) skal returnere sekvensen av ord (med mellomrom mellom) i en String som tilsvarer ordet som gis som parameter. Bokstaver som ikke kan oversettes skal ignoreres. F.eks. skal convert( *abba* ) returnere alfa bravo bravo alfa. Det enkleste er å bruke List/ArrayList eller en Map/HashMap, siden disse har dynamisk størrelse. En Map gir kanskje aller enklest kode (litt mer kompleks konstruktør), men her vises en løsning som bruker List. Lista inneholder kun alfabet-ordene og koden utnytter at første bokstav i ordet er nettopp bokstaven som ordet er oversettelsen av. Split bør være kjent og gir en enklere konstruktør. Merk hvordan pos-metoden, som finner hvor ordet for en bokstav er, brukes av flere av de andre metodene. I convert-metoden kan bruke String +=, StringBuilder.append eller StringBuffer.append. Merk at det kreves egen logikk for å unngå unødvendige blanke tegn, foran inni eller i slutten av String en. Siden en bokstav ikke nødvendigvis kan oversettes, er det ikke nok å sjekke indeksen for å avgjøre om det skal legges inn mellomrom. Her løses det delvis med en if, delvis med String.trim. public class RadioAlphabet { private List<String> alphabet; public RadioAlphabet(String alphabet, String separator) { this.alphabet = new ArrayList<String>(Arrays.asList(alphabet.split(separator))); Side 5 av 10

private int pos(char c) { for (int i = 0; i < alphabet.size(); i++) { if (alphabet.get(i).charat(0) == c) { return i; return -1; public String convert(char c) { int pos = pos(c); return pos >= 0? alphabet.get(pos) : null; public String convert(string word) { StringBuffer /* or StringBuilder */ buffer = new StringBuffer(); for (int i = 0; i < word.length(); i++) { String converted = convert(word.charat(i)); if (converted!= null) { buffer.append(converted); buffer.append(' '); return buffer.tostring().trim(); b) Hvorfor kan ikke disse metodene være deklarert med static-modifikatoren? Med static-modifikatoren vil metodene ikke kunne referere til et bestemt RadioAlphabet-objekt. En kan for så vidt gjøre alfabetet static også, men da vil en bare kunne ha ett globalt alfabet. c) Hva kalles det når metoder i samme klasse (som convert-metodene) har samme navn? Hva er regelen for å skille dem fra hverandre/velge mellom dem, når de brukes/kalles? At metoder i en klasse kan ha samme navn kalles overloading. For å avgjøre hvilken som skal kalles, brukes de deklarerte typene til argumentene (ikke returverdien). Merk at dette er noe annet enn polymorfi, som handler om at subklasser kan ha ulike implementasjoner av metoder definert i en felles superklasse. d) Utvid klassen med metodene setword(string) som endrer ordet som brukes for en bestemt bokstav (første bokstav i ordet), og removeword(char) som fjerner ordet for en bestemt bokstav fra alfabetet. Merk at setword skal kun kunne endre ordet for en bokstav som allerede finnes i alfabetet. Her brukes pos-metoden som også ble brukt av convert(char). Merk at setword ikke skal legge inn et nytt ord, kun erstatte et eksistererende. public void setword(string word) { int pos = pos(word.charat(0)); if (pos >= 0) { alphabet.set(pos, word); Side 6 av 10

public void removeword(char c) { int pos = pos(c); if (pos >= 0) { alphabet.remove(pos); Del 4 Testing (10%) a) Skriv en JUnit-testklasse som tester begge convert-metodene i RadioAlphabet-klassen. Du kan anta at konstruktøren virker. Vi er ikke så nøye på detaljene, bare den generelle testeteknikken er riktig. Det sentrale her er å rigge opp et test-objekt og å bruke relevante testdata, inkludert bokstaver som ikke har noen oversettelse og ikke-bokstaver. Som nevnt er vi ikke opptatt at JUnit-spesifikke detaljer, men dersom en ikke bruker JUnit-metoder, så bør en selv definere egne assert-aktige hjelpemetoder. private RadioAlphabet radioalphabet; @Override protected void setup() throws Exception { // TODO Auto-generated method stub super.setup(); radioalphabet = new RadioAlphabet(alphabet, "-"); public void testconvertchar() { assertequals("alfa", radioalphabet.convert('a')); assertequals("hotel", radioalphabet.convert('h')); assertequals("zulu", radioalphabet.convert('z')); assertnull(radioalphabet.convert('!')); public void testconvertstring() { assertequals("hotel alfa lima lima victor alfa romeo delta", radioalphabet.convert("hallvard")); assertequals("hotel alfa lima alfa lima", radioalphabet.convert("!h!a!l!a!l?")); radioalphabet.setword("åring"); assertequals("hotel victor alfa romeo delta", radioalphabet.convert("håvard")); b) Forklar hvordan du vil teste setword- og removeword-metodene i RadioAlphabet-klassen vha. JUnit-teknikken. Hva er en vesentlig (kompliserende) forskjell mellom å teste disse metodene og å teste convert-metodene? Det vesentlige her er at en må teste oppførselen både før og etter bruken av endringsmetoden, i praksis at convert fungerer ulikt før og etter bruk av setword og removeword. Det kan synes som om det kun er nødvendig å teste oppførselen etterpå, fordi en tross alt har andre tester for oppførsel også. Men det er riktig å test både før og etter, for at testen skal dekke tilfellet alene. Side 7 av 10

public void testsetword() { assertequals("hotel alfa lima lima victor alfa romeo delta", radioalphabet.convert("hallvard")); radioalphabet.setword("lala"); assertequals("hotel alfa lala lala victor alfa romeo delta", radioalphabet.convert("hallvard")); public void testremoveword() { assertequals("hotel alfa lima lima victor alfa romeo delta", radioalphabet.convert("hallvard")); radioalphabet.removeword('l'); assertequals("hotel alfa victor alfa romeo delta", radioalphabet.convert("hallvard")); Del 5 Arv og observerbarhet (25%) a) Morse-alfabetet er et alfabet hvor bokstaver (og andre tegn) representeres med sekvenser av prikker og streker. F.eks. skrives det internasjonale nødsignalet SOS som... ---... fordi s skrives som... og o som ---. Du skal lage en subklasse av RadioAlphabet-klassen kalt MorseAlphabet, som støtter dette alfabetet. F.eks. skal new MorseAlphabet() gi et ferdiginitialisert objekt som kan konvertere sos til... ---... og test til -.... -". convert-metodene og removeword skal virke som spesifisert i del 3. setword-metoden må nødvendigvis endres slik at den tar inn tegnet som første argument og ordet som andre. Det er et mål å utnytte arv slik at det blir mest mulig gjenbruk av kode, f.eks. ved at en eller flere av de arvede metodene ikke trenger å redefineres. Forklar med tekst og kode hvordan du vil gjøre dette. Forklar om nødvendig hvordan du må endre på RadioAlphabet-klassen for å få det til, men merk at den må fortsatt virke slik det er beskrevet i del 3. Besvarelser vurderes ut fra korrekthet og grad av gjenbruk. Noen løsninger på del 3, vil egne seg bedre til gjenbruk enn andre, så vi må delvis vurdere ut fra det vi oppfatter som potensialet for gjenbruk. Det teller positivt at en reflekterer over om en kunne økt graden av gjenbruk, dersom en hadde skrevet om RadioAlphabet slik og slik, selv om en ikke har hatt tid til å gjøre det. Generelt så er det best om en kan gjenbruke logikk som allerede er public. protected-metoder foretrekkes fremfor protected-felt. Med vår løsning blir det lite ekstra kode, siden den eksisterende representasjonen med forbokstav og ord i ett kan også brukes for morsealfabetet. Hvert element i lista vil være tegnet foran prikkene og strekene, f.eks. s... og o---. Trikset er å utnytte superklassens metoder, ved å justere på argument/returverdi. convert(char) kaller super-metoden og fjerner første bokstav. Den nye setwordmetoden kaller superklassens setword-metode med tegnet lagt foran ordet. Convert(String) og remove-metoden arves i sin helhet. public class MorseAlphabet extends RadioAlphabet { private final static String morsealphabet = "s... o--- e. t-"; public MorseAlphabet() { super(morsealphabet, " "); Side 8 av 10

public String convert(char c) { String word = super.convert(c); return (word!= null? word.substring(1) : null); public void setword(char c, String word) { super.setword(c + word); b) Du skal gjøre RadioAlphabet-klassen (og dermed også subklassen) såkalt observerbar, vha. følgende lyttergrensesnitt: public interface RadioAlphabetListener { public void radioalphabetchanged(radioalphabet, char); Dersom en RadioAlphabet-instans endres, skal altså metoden radioalphabetchanged kalles på alle lytterne, med RadioAlphabet-instansen som første argument og tegnet viss ord ble endret/fjernet som det andre. Beskriv hvordan RadioAlphabet og evt. MorseAlphabet må endres for å implementere denne oppførselen. Observerbarhet krever 1) at en holder styr på lytterne og 2) at alle endringsmetoder kaller lytternes lyttermetode. Med vår løsning trenger en faktisk ikke å endre MorseAlphabet, siden metodene for 1) arves og all endring 2) skjer gjennom arvede metoder. 1) Holder styr på lytterne private List<RadioAlphabetListener> listeners = new ArrayList<RadioAlphabetListener>(); public void addradioalphabetlistener(radioalphabetlistener listener) { listeners.add(listener); public void removeradioalphabetlistener(radioalphabetlistener listener) { listeners.remove(listener); 2) Alle endringsmetoder kaller lytternes lyttermetode: protected void fireradioalphabet(char c) { for (RadioAlphabetListener listener : listeners) { listener.radioalphabetchanged(this, c); public void setword(string word) { int pos = pos(word.charat(0)); Side 9 av 10

if (pos >= 0) { alphabet.set(pos, word); // added fireradioalphabet(word.charat(0)); public void removeword(char c) { int pos = pos(c); if (pos >= 0) { alphabet.remove(pos); // added fireradioalphabet(c); Side 10 av 10