1 (8) TENTAMEN: Objektorienterad programmering Läs detta! Uppgifterna är inte ordnade efter svårighetsgrad. Börja varje hel uppgift på ett nytt blad. Skriv inte i tesen. Ordna bladen i uppgiftsordning. Skriv din tentamenskod på varje blad (så att vi inte slarvar bort dem). Skriv inte med rödpenna! Skriv rent dina svar. Oläsliga svar r ä t t a s e j! Programkod som finns i tentamenstesen behöver ej upprepas. Programkod skall skrivas i Java 5, eller senare version, och vara indenterad och renskriven. Onödigt komplicerade lösningar ger poängavdrag. Givna deklarationer, parameterlistor etc. får ej ändras. Läs igenom tentamenstesen och förbered ev. frågor. I en uppgift som består av flera delar får du använda dig av metoder klasser etc. från tidigare deluppgifter, även om du inte löst dessa. Lycka till!
2 (8) Uppgift 1 Välj ett alternativ för varje fråga! Garderingar ger noll poäng. Inga motiveringar krävs. Varje korrekt svar ger två poäng. Besvara delfrågorna 1.1-1.5 på ett blad. 1. Vilket påstående är falskt? a. testning kan påvisa förekomsten av fel i ett program b. avlusning kan avslöja orsaken till fel i ett program c. testning och avlusning är samma sak d. regresionstestning bör utföras efter refaktorering 2. Antag att man vill införa metoden equals i klassen Point. Eftersom det av numeriska skäl inte är lämpligt att jämföra om två flyttal är lika med operatorn == kan man tänka sig att istället definiera likhetsrelationen så att två punkter betraktas som lika om de är tillräckligt nära varandra. public class Point { private double x,y; public double distanceto(point other)... public boolean equals(...) {... return distanceto(other) < 0.00000001; Vilket av påståendena är sant? a. likhetsrelationen blir reflexiv, symmetrisk och transitiv b. likhetsrelationen blir inte symmetrisk c. likhetsrelationen blir inte transitiv d. likhetsrelationen blir inte reflexiv 3. Studera följande klasser: public class Base { private int x; private String s; public Object clone() { Base temp = new Base(); temp.x = x; temp.s = s; return temp; // Other details omitted Vad händer då main exekveras? a. inget oväntat eftersom koden så långt man kan se är korrekt b. ett NullPointerException kastas c. ett ClassCastException kastas d. ett CloneNotSupportedException kastas e. minnet tar slut public class Sub extends Base { // Details omitted public class Main { public static void main(string[] arg) { Sub obj = new Sub(); Sub b = (Sub)obj.clone();
3 (8) 4. I ett bokningsprogram för entimmesmöten finns följande klasser: public class Booking { private String what; private String where; private String who; public Booking(String what,string where,string who) { this.what = what; this.where = where; this.who = who; public void printinfo() { System.out.println(what + "," + where + "," + who); public class Calendar { private Booking[] bookings = new Booking[24]; public void schedule(int hour,string what,string where,string who) { bookings[hour] = new Booking(what,where,who); public void printday() { for ( int h = 0; h < 24; h++ ) { System.out.print(h + "-" + (h+1) + ": "); bookings[h].printinfo(); public class CalendarMain { public static void main(string[] arg) { Calendar c = new Calendar(); c.schedule(0,"nattdugga","j123","uh"); c.schedule(8,"morgontenta","sv219","nn"); c.schedule(15,"fika","lunchrummet","bg"); c.printday(); Vad är sant? a. koden kompilerar inte p.g.a. ett typfel b. namnet Calendar får inte användas eftersom en standardklass i Java API heter så c. ett NullPointerException kastas då main exekveras. d. fält (arrayer) kan bara lagra primitiva datatyper, inte objekt e. programmet producerar en komplett utskrift för hela dygnet 5. Vilken/vilka av satserna S1 S4 ger kompileringsfel? a. S1 och S3 b. S2 och S4 c. S3 och S4 d. S3 e. S1 f. alla utom S1 public class C { private int x; private static int y; public static void f(c obj) { x = 3; // S1 y = 42; // S2 obj.x = 3; // S3 obj.y = 42; // S4 (10 p)
4 (8) Uppgift 2 Klassen Point kan användas för att representera punkter i 2D-planet. public class Point { private int x,y; private long modcount = 0; public Point(int x,int y) { this.x = x; this.y = y; public int getx() { return x; public int gety() { return y; public long getmodcount() { return modcount; public void setx(int x) { this.x = x; modcount++; public void sety(int y) { this.y = y; modcount++;... // ToDo Ex. Point p = new Point(11,32); p.setx(7); p.sety(9); p.getmodcount() -> 2 Variabeln modcount håller reda på hur många gånger objektet modifierats. Den skall vara 0 för alla nya objekt. a) Lägg till metoden equals till Point. Två punkter är lika om deras x- resp. y-koordinater är parvis lika. (4 p) b) Lägg till metoden hashcode i Point. (2 p) c) Lägg till metoden clone i Point. d) I klassen Polygon lagras hörnpunkterna för en polygon som objekt av typen Point. Vi går inte in i detalj på denna klass utan visar bara en mindre del. Uppgiften är att införa en clone-metod i klassen: public class Polygon { private ArrayList<Point> points = new ArrayList<>(); public void add(point p) { points.add(p);... // ToDo: clone // Other methods omitted (5 p)
5 (8) Uppgift 3 Begreppet implementationsarv innebär att en klass ärver tillstånd (instansvariabler) och metoder från en annan klass, och detta är ju en typ av arv som har behandlats i kursen. Vi kan t.ex. deklarera en klass Person för personuppgifter, som den nedan, och senare göra specialiserade subklasser till Person för att t.ex. laga information om studenter, anställda och idrotsutövare. public class Person { private String CID; private String name; private String address; private String phone; private String email; public Person(String CID,String name,string address, String phone,string email) { this.cid = CID; this.name = name; this.address = address; this.phone = phone; this.email = email; public void setaddress(string newaddress) { address = newaddress; // other methods omitted Subklassen Student skall ha instansvariabler för program (sträng), antagningsår (heltal) samt uppnådda poäng (heltal). Subklassen Employee skall ha instansvariabler för lön (heltal) och antal semesterdagar (heltal). Subklassen Athlete skall ha instansvariabler för kroppslängd (heltal) och vikt (heltal). a) Konstruera en av subklasserna Student, Employee eller Athlete. Välj själv vilken! b) Skriv en main-metod som skapar ett objekt vardera av klasserna Student, Employee och Athlete. Använd data från tabellen nedan: För Student: "123456-7890","Bob","Postgatan 20","0123-4567890","bob@mail.org","D",2016,85 För Employee: "123456-7890","Bob","Postgatan 20","0123-4567890","bob@mail.org",45000,35 För Athlete: "123456-7890","Bob","Postgatan 20","0123-4567890","bob@mail.org",168,74 Avsluta main-metoden med att ändra adress för Bob som just flyttat, hans nya adress skall vara Telefongränd 7. c) Som du säkert lagt märke till leder användning av implementationsarv i exemplet ovan till kodduplicering vilket inte är önskvärt. Ett alternativt till arv är att låta klasserna Student, Employee och Athlete delegera personuppgiftshanteringen till klassen Person istället för att ärva från klassen: forts.
6 (8) Skriv om din klass i a) så att den istället för att ärva från Person delegerar till ett Personobjekt som skall vara inparameter till klassens konstruktor. d) Skriv om main-metoden i b baserat på resultatet i c. Uppgift 4 a) Studera klasserna nedan: public class Base { public int f(int x,int y) { return g(x+y); public int f(int x) { return x + 42; public int g(int x) { return 3*f(x); public int h(int x) { return 4*f(x-1); public class Sub extends Base { public int f(int x) { return x + 11; public int g(int x) { return 2*h(x); Vilket värde returnerar f? Motivera svaret! Base obj = new Sub(); obj.f(2,3); b) Ett av metodanropen i main kompilerar inte eftersom en av klasserna (ej Main) ger kompileringsfel, vilken klass och varför? Vad skrivs ut av de övriga anropen i main? (5 p) public class Main { public static void func(a obj) { try { obj.f(); catch (E3 e) { System.out.println("func catch E3:"+e.getMessage()); catch (E2 e) { System.out.println("func catch E2:"+e.getMessage()); public static void main(string[] arg) { func(new A()); func(new B()); func(new C()); public class A { public void f() throws E2,E3 { throw new E2("A.f throwed E2"); public class E1 extends Exception { public E1(String msg) { super(msg); public class E2 extends E1 { public E2(String msg) { super(msg); public class E3 extends E2 { public E3(String msg) { super(msg); public class B extends A { public void f() throws E2 { throw new E3("B.f throwed E3"); public class C extends B { public void f() throws E1 { throw new E1("C.f throwed E1"); (5 p)
7 (8) Uppgift 5 I denna uppgift ingår att konstruera delar till ett mycket enkelt program för hantering av labredovisningar - liknande Fire-systemet som används i denna kurs. Det finns två färdiga klasser ( {... betyder att metoden är färdig): * Submission Objects of this class stores information * about lab submissions. public class Submission { public Submission(int labno,string content,string grader) {... public int getlabno() {... public String getcontent() {... public String getgrader() {... public String getcomment() {... public String getstatus() {... public void setcomment(string comment) {... public void setgrader(string grader) {... public void setstatus(submissionstatus status) {... Anm. Metoden getstatus returnerar ett av följande tre värden: PENDING, REJECTED eller ACCEPTED. * GroupAccount Stores account credentials and submissions for a student. public class GroupAccount implements Iterable<Submission> { public GroupAccount(int groupid,string email,string password, int nooflaborations) {... public void submit(submission s) throws DuplicateSubmissionException { public int getgroupid() {... public String getemail() {... public void setemail(string email) {... public String getpassword() {... public void setpassword(string password) {... public Iterator<Submission> iterator() {... Iteratorn som retureras av metoden iterator genomlöper inlämningarna i nummerordning. Iteratorns next metod returnerar nästa inlämning i nummerordning om den finns, annars null. Ex. Om man postat lab 1 och lab 3 av fyra så kommer next att returnera lab1, null, lab3 och till sist null. Konstruera klassen Fire med hjälp av ovanstående klasser. public class Fire { public Fire(int nooflaborations) // ToDo * signup Create an account for a given user and password. * @param email The user's e-mail address. * @param password The password to the account. * @return A unique group number identifying the new account but * -1 if an account using the given e-mail address * already exists. public int signup(string email,string password) // ToDo forts.
8 (8) * submit Submit a lab report to this Fire instance. * @param groupid The id of the group submitting the lab. * @param labno A positive integer identifying the lab. * @param content The actual submission. * @return A string identifying the grading teacher. * @throws UnknownAccountException if groupid is invalid. * @throws DuplicateSubmissionException if a submission for labno * already exists. * @throws IllegalLaborationNoException if labno is not a legal * laboration id. public String submit(int groupid,int labno,string content) // ToDo throws UnknownAccountException, DuplicateSubmissionException, IllegalLaborationNoException * printresulttable Print a status report for all groups. * Unsubmitted labs are marked with a "-". * Submitted labs are marked as PENDING, REJECTED or ACCEPTED public void printresulttable() // ToDo Undantagsklasserna UnknownAccountException, DuplicateSubmissionException, IllegalLaborationNoException är alla subklasser till Exception och de är färdiga. Lagra informationen i en map. Resultattabellen som skrivs ut av printresulttable skall se ut enligt följande men den exakta formatteringen av raderna är mindre viktig, labgruppnumret längst till vänster. I exemplet har kursen tre laborationer och tre registrerade labgrupper: 1 ACCEPTED REJECTED PENDING 2 REJECTED PENDING - 3 - ACCEPTED REJECTED (14 p)