Institutionen för TENTAMEN CTH VT-16 Datavetenskap 2016-01-13 TDA550 Tentamen för TDA550 Objektorienterad programvaruutveckling IT, fk DAG: 16-01-13 TID: 14:00 18:00 Ansvarig: Christer Carlsson, ankn 1038 Förfrågningar: Christer Carlsson Resultat: erhålls via Ladok Betygsgränser: 3:a 24 poäng 4:a 36 poäng 5:a 48 poäng maxpoäng 60 poäng Siffror inom parentes: Granskning: Hjälpmedel: Var vänlig och: Observera: anger maximal poäng på uppgiften. Tisdag 9/2 kl 12-13 och tisdag 16/2 kl 12-13, rum 6128 i EDIT-huset. Inga hjälpmedel är tillåtna förutom bilagan till tesen. Skriv tydligt och disponera papperert på lämpligt sätt. Börja varje uppgift på nytt blad. Skriv ej på baksidan av papperet. Uppgifterna är ej ordnade efter svårighetsgrad. Titta därför igenom hela tentamen innan du börjar skriva. Alla program skall vara välstruktruerade, lätta att överskåda samt enkla att förstå. Vid rättning av uppgifter där programkod ingår bedöms principella fel allvarligare än smärre språkfel. LYCKA TILL!!!!
Uppgift 1. Betrakta nedanstående klasser och interface: public interface A{ public void a(); //A public interface B{ public void b(); //B public class C implements A{ public void a(){ System.out.println( "a() in C" ); //a public void c(){ System.out.println( "c() in C" ); //c //C public abstract class D extends C implements B { public void c(){ System.out.println( "c() in D" ); //c //D public class E extends D{ public void b(){ System.out.println( "b() in E" ); //b //E public class F extends C implements B{ public void b(){ System.out.println( "b() in F" ); //b //F Vad blir resultatet för var och en av följande satser (ger kompileringsfel, ger exekveringsfel, skriver ut xxx, etc)? a) C x = new E(); x.c(); b) Object o = new E(); System.out.println( o instanceof D ); c) C x = new D(); x.c(); d) B x = new E(); D y = (D) x; y.b(); e) C x = new F(); x.b(); f) D x = new C(); x.a(); g) B x = new F( ); D y = (D) x; x.b(); h) A x = new F(); C y = x; y.a(); Tips: Rita klassdiagram! (8 poäng) Uppgift 2. Följande klass finns i ett program som hanterar medlemmar i en golfklubb: public class Member { public final static int SENIOR = 1, JUNIOR = 2, PASSIVE = 3; private int membership; private String name; public String payment ( ) { switch (membership) { case SENIOR: return name + ", your membership fee is " + 3000; case JUNIOR: return name + ", your membership fee is " + 1800; case PASSIVE: return name + ", your membership fee is " + 500 ; return "" ; Klassen Member är bristfällig eftersom man inte kan lägga till nya typer av medlemskap utan att ändra i metoden payment. Vidare kan en medlem inte byta typ av medlemskap. Åtgärda dessa brister genom att göra en ny design som använder designmönstret Strategy. (6 poäng)
Uppgift 3. a) Betrakta nedanstående fyra specifikationer för metoden int getprice(string item) som finns i en klass som handhar matsedeln på en restaurang. I) @requires item is not null and item appears in the menu @return the price of the item II) III) @requires item is not null @return the price of the item if it appears in the menu, or 0 if the item is not found in the menu @requires item is not null @return the price of item @throws NoSuchElementException if item is not found in menu IV) @return the price of the item if it appears in the menu, or 0 if the item is not found in the menu @throws NullPointerException if item is null För vart och ett av nedanstående par av specifikationer, ange vilken specifikation som är starkast. Om detta inte går att avgöra svara att de är lika starka. i) I och II ii) I och III iii) I och IV iv) II och III v) II och IV vi) III och IV (3 poäng) b) Nedan finns fyra möjliga implementationer av metoden getprice: Implementation 1: public int getprice(string item) { return items.get(item); Implementation 3: public int getprice(string item) { assert(item!= null); Integer price = items.get(item); if (price == null) { return 0; else { return price; Implementation 2: public int getprice(string item) { if (item == null) { throw new NullPointerException(); return items.get(item); Implementation 4: public int getprice(string item) { assert(item!= null); Integer price = items.get(item); if (price == null) { throw new NoSuchElementException(); return price; Instansvariabeln items är definieras som HashMap<String, Integer> items = new HashMap<String, Integer>(); i) Vilka av ovanstående specifikationer uppfyller implementation 1 ii) Vilka av ovanstående specifikationer uppfyller implementation 2 iii) Vilka av ovanstående specifikationer uppfyller implementation 3 iv) Vilka av ovanstående specifikationer uppfyller implementation 4 (2 poäng)
Uppgift 4. Betrakta nedanstående klasser (utlämnad kod är betydelselös för uppgiften): public class Matching<T1, T2> { public void addpair(t1 x, T2 y) {... public T1 getmatchright(t2 x) {... public T2 getmatchleft(t1 x) {... public class OptionallyMatching<T1, T2, T3> extends Matching<T1, T2> { public void setlabel(t1 x, T2 y, T3 z) {... public T3 getlabel(t1 x, T2 y) {... public class Socks {... public class FancySocks extends Socks {... public class Shoes {... public class PrettyShoes extends Shoes {... Antag att följande deklarationer har gjorts Socks socks = new Socks(); FancySocks fancysocks = new FancySocks(); Shoes shoes = new Shoes(); PrettyShoes prettyshoes = new PrettyShoes(); Number n = new Integer(42); Matching<Socks, Shoes> m1 = new Matching<Socks, Shoes>(); Matching<FancySocks, PrettyShoes> m2 = new Matching<FancySocks, PrettyShoes>(); Matching<? extends Socks,? extends Shoes> m3; OptionallyMatching<Socks, Shoes, Integer> om1 = new OptionallyMatching<Socks, Shoes, Integer>(); Ange för var och en av nedanstående satser om satsen är korrekt eller ger kompileringsfel. Motivera! Uppgift 5. a) m1 = m2; b) m1 = om1; c) m1.addpair(socks, prettyshoes); d) prettyshoes = m1.getmatchleft(socks); e) om1.setlabel(socks, prettyshoes, n); f) n = om1.getlabel(fancysocks, prettyshoes); g) m3 = m2; h) m3.addpair(socks, shoes); Betrakta nedanstående klasser: public class Course implements Cloneable, Serializable { //... implementation are omitted for the sake of brevity //Course public class Student { private List<Course> courses; private String name; private int year; private double gpa; //... constructors and methods are omitted for the sake of brevity //Student (4 poäng) a) Överskugga (implementera) metoden clone() i klassen Student. Djup kloning skall användas. (4 poäng) b) Gör de tillägg som behövs för att kunna skriva ut objekt av klassen Student på en fil. (1 poäng)
Uppgift 6. DVI- respektive VGA-kablar implementerar följande interface: public interface DVICable { public void transferdvisignal(int transfersignal); public interface VGACable{ public void transfervgasignal(int signal); //VGACable Vi har ett har ett klientprogram som nyttjar sig av en VGA-kabel enligt: public class Client { private VGACable cable; private int data; public Client(VGACable cable) { this.cable = cable; public void senddata() { cable.transfervgasignal(data); //code omitted Vi har dock inte tillgång till någon implementation av interfacet VGACable men däremot en implementation av intrfacet DVICable: public class DualDVI implements DVICable { public void transferdvisignal(int transfersignal) { //code omitted System.out.println("Transfering DVI signal: " + transfersignal); //transferdvisignal //DualDVI Använd designmönstret Adapter för att implementera en klass SignalAdapter som anpassar gränssnittet för typen VGACable till gränssnittet för typen DVICable. (5 poäng) Uppgift 7. Pelle Hacker håller på och utvecklar ett röstningssystem. Rösterna utgörs av strängar och Pelle lagrar dessa i en lista av typen List<String> enligt: ["Lind", "Andersson", "Steen", "Åhs", "Andersson", "Ek",..., "Steen", "Lind"] Du skall nu hjälpa Pelle med att räkna samman hur många röster var och en får. Detta gör du genom att specificera klassen VoteCounter: public class VoteCounter { /** Räknar antal olika slags element i listan votes och returnerar resultatet i en map med par av element och dess antal förekomster. */ public static <E> Map<E, Integer> result(list<e> votes) { //skall du implementera i deluppgift a) //VoteCounter När denna klass är implementerad (på ett korrekt sätt) kan Pelle erhålla resultatet av röstningen på formen {Åhs=13, Andersson=22, Lind=9,..., Steen=18 genom följande kodsekvens: List<String> list = //Listan med röster Map<String, Integer> resultmap = VoteCounter.result(list); System.out.println(resultMap);
a) Skriv klart metoden result i klassen VoteCounter. (8 poäng) b) Nu när du är klar med implementationen av klassen VoteCounter kommer Pelle och säger du behöver skriva om metoden result, eftersom han beslutat sig för att lagra rösterna i en lista av typen List<Candidat> istället för i en lista av typen List<String>. Klassen Candidat har följande utseende: public class Candidate { private String personnumber; private String name; private String address; public Candidate(String personnumber, String name, String address) { this.personnumber; = personnumber; this.name = name; this.adress = address; public String getpersonnumber() { return personnumber; public String getname() { return name; public String getaddress() { return address; public String tostring() { return name; //Candidate Du kan dock upplysa Pelle om att metoden result inte behöver förändras, eftersom du varit förutseende och gjort den generisk. Däremot påpekar du för Pelle att klassen Candidate måste överskugga metoderna hashcode och equals, samt implementera interfacet Comparable, för att med säkerhet erhålla en korrekt sammanräkning av rösterna ifall en lista av typen List<Candidat> används istället för en lista av typen List<String>. i) Förklara varför det är nödvändigt att klassen Candidate överskuggar metoderna hashcode och equals samt implementera interfacet Comparable. Ange också vilket kontrakt som måste gälla mellan hashcode och equals. (2 poäng) Uppgift 8. ii) Hjälp Pelle att implementera dessa kompletteringarna i klassen Candidate. Betrakta nedanstående klasser: public class Model { private Gui gui; private int state; // attribute representing the state public Model(Gui gui) { this.gui = gui; public void changestate() { // commands changing the state gui.showstate(state); //Model public class Gui extends JFrame { public void showstate(int state) { // display state //Gui public class Main { public static void main(string [] arg) { Model m = new Model(new Gui()); m.changestate(); m.changestate(); m.changestate(); (3 poäng) Ovanstående design är bristfällig eftersom modellen (klassen Model) känner till vyn (klassen Gui). Modifiera designen med användning av Observer-mönstret så att klassen Model kan kompileras utan tillgång till klassen Gui. (6 poäng)
Uppgift 9. Betrakta klassen Auction nedan som utgör en av komponenterna i ett system för att handha auktioner över nätet (du behöver inte förstå alla detaljerna för att kunna lösa uppgiften): public class Auction extends Thread { currentbid private int currentbid; holds the current highest private String highestbidder = "Nobody"; bid. private boolean biddingopen = true; highestbidder holds the name of of the public Auction (int minbid) { bidder who has the highest bid. currentbid = minbid; biddingopen has the value true if if the /* Return the current highest bid. */ public synchronized int getcurrentbid () { return currentbid; /* Return name of the bidder who has the highest bid. */ public synchronized String gethighestbidder() { String bidder = highestbidder; return highestbidder; /* Return true if the auction is going on, else false. */ public synchronized boolean biddingallowed () { return biddingopen; /* Close the auction. */ private synchronized void closebidding () { biddingopen = false; /* Will accept newbid from thebidder if the bid is higher than currently offered bid. If the bid is accepted, */ /* bidder thread blocks here until another bidder give a higher bid or the bidder wins the auction. */ public synchronized void setbid (int newbid, String thebidder) { if (newbid > currentbid) { highestbidder = thebidder; currentbid = newbid; System.out.println("Bid of " + currentbid + " from " + thebidder + " accepted"); notifyall(); try { while (biddingallowed() && thebidder == highestbidder) wait(); catch (InterruptedException e) {; public void run() { while (biddingallowed()) { int lastbid = currentbid; try { sleep(3000); catch (InterruptedException e ){ if (lastbid == currentbid) closebidding(); System.out.println("Sold to " + highestbidder); //Auction auction is is going on, else the value false. Lowest bid accepted must be higher than minbid. Checks each three seconds to to see if if the current highest bid has been raised. If If not the auction ends and the goods goes to to last highest bidder.
För att få till stånd en auktion måste det också finnas budgivare. Din uppgift är att implementera klassen public class Bidder extends Thread som modellerar budgivarna i auktionen. I nedanstående main-metod framgår hur en auktion med tre budgivare skapas. public class Main { public static void main (String [] args) { Auction aution = new Auction(110); Bidder bidder1 = new Bidder ("Bidder 1", aution, 170); Bidder bidder2 = new Bidder ("Bidder 2", aution, 120); Bidder bidder3 = new Bidder ("Bidder 3", aution, 150); aution.start(); bidder1.start(); bidder2.start(); bidder3.start(); //Main Exempel på utskrift: Bid of of 111 from Bidder 1 accepted Bid of of 112 from Bidder 2 accepted... Bid of of 148 from Bidder 1 accepted Bid of of 149 from Bidder 3 accepted Bid of of 150 from Bidder 1 accepted Sold to to Bidder 1 Klassen Bidder har en konstruktor med tre argument - budgivarens namn, vilken auktion budgivaren skall delta i samt hur högt bud budgivaren är villig att ge. En budgivare deltar i auktionen så länge som det lagda budet ligger lägre än vad budgivaren själv är villig att ge eller så länge som auktionen pågår. I det senare fallet har budgivaren vunnit budgivningen. En budgivare höjer alltid det lagda budet med 1. I din implementation av Bidder skall du låta tråden sova en slumpmässig tid, om max en sekund, mellan varje budgivning. (8 poäng)