// Konteeksamen i IN1010 og INF1010 våren 2019 // Løsningsforslag og sensorveiledning oppgave 1-8 import java.util.ArrayList; import java.util.Iterator; // Oppgave 1 Tegning av klassehierarki . 7% // Her skal studentene vise at de skjønner og kan lage et klassehierarki // Det må angis hva som er klasser og hva som er interfacer // Det må tydelig angis hvordan en klasse arver, både fra interface(r) og en superklasse // Klassen EgetBildeMøbel kan enten være slik som beskrevet under, eller den kan // være en suklasse av EgetInventar og implementere både Bilde og Mobel. // Oppgave 2 Programmering av klassehierarki. 13% // Her skal studentene vise at de skjønner og kan programmer interfacer og klasser. // Det er spesielt viktig at de // - lager en abstrakt metode i hver av interfacene // - implementerer denne metoden i subklassene // - bruker både "extends" og "inplements" riktig i subklassene // - kaller på konstruktøren i superklassen med riktige parametre. // - finnForsikringsverdi må være riktig definert i klassen EgetInventar // (Det står ikke angitt om finnForsikringsverdi skal returnere en int // eller en double, så begge deler er OK.) // Klassen Inventar skal helst være abstrakt. interface Bilde { double bredde(); } interface Mobel { double areal(); } abstract class Inventar implements Comparable { String navn; int verdi; Inventar neste; Inventar(String navn, int verdi) { this.navn = navn; this.verdi = verdi; neste = null; } abstract double finnForsikringsverdi(); public int compareTo(Inventar i) { return verdi - i.verdi; } // Oppgave 6 14% // Her skal studentene vise at de kan skrive en rekursiv metode. // Rekursjonen må stoppe når enden av listen er nådd, // ellers må rekursjonen fortsette og returnere summen av egen verdi og resten. // Resten av svaret på oppgave 6 kommer lenger ned. double finnSummenAvForsikringsverdier() { if (neste == null) return finnForsikringsverdi(); return finnForsikringsverdi() + neste.finnSummenAvForsikringsverdier(); } } // Oppgave 2 (fortsetter her) abstract class EgetInventar extends Inventar { int innkjopsaar; EgetInventar(String navn, int verdi, int aar) { super(navn, verdi); innkjopsaar = aar; } double finnForsikringsverdi() { return 0.8 * verdi; } } class EgetBilde extends EgetInventar implements Bilde { double aktBredde; EgetBilde(String navn, int verdi, int aar, double br) { super(navn, verdi, aar); aktBredde = br; } public double bredde() { return aktBredde; } } // Klassen EgetBildeMøbel kan også være en subklasse av EgetInventar // og implementere både Bilde og Mobel class EgetBildeMobel extends EgetBilde implements Mobel { double aktAreal; EgetBildeMobel(String navn, int verdi, int aar, double br, double ar) { super(navn, verdi, aar, ar); aktAreal = ar; } public double areal() { return aktAreal; } } // Oppgave 3 7% // Her skal studentene vise at de kan skrive klasser som inneholder forskjellige // datastrukturer. // Klassen Skip må inneholde en array med referanser til alle rommene, en førstepeker // (altInventar) til listen over alt inventar og en konstruktør som angir antall rom. // Oppgave 7 Iterator 10% // Her skal studentene vise at de kan iterere over en liste. // Klassen Skip må implementere Iterable . class Skip implements Iterable { Inventar altInventar = null; Rom[] rom; int antallRom; Skip(int ant) { rom = new Rom[ant]; antallRom = ant; } // Oppgave 4 5% // Her skal studentene vise at de kan programmere en metode som setter elementer // inn i flere beholdere. Settinn-metoden i riktig rom må kalles og gulvplass og // veggplass må oppdateres (se lenger nede). // Inventaret må settes inn først i den lenkede listen i skipet. void settInn(Inventar inv, int nr) { rom[nr].settInn(inv); inv.neste = altInventar; altInventar = inv; } // Oppgave 5 7% // Her skal studentene vise at de kan lage og bruke et egendefinert unntak. // Studentene må teste om det er ledig plass på vegg og gulv før inventaret settes inn, // f.eks. ved å lage egne metoder som tester at det er nok gulv og veggplass // (se nedenfor). void settInn2(Inventar inv, int nr) throws ForLiteGulvplass, ForLiteVeggplass { double ar = 0, br = 0; if (inv instanceof Mobel) ar = ((Mobel)inv).areal(); if (inv instanceof Bilde) br = ((Bilde)inv).bredde(); if (! rom[nr].ledigAreal(ar)) throw new ForLiteGulvplass(); if (! rom[nr].ledigBredde(br)) throw new ForLiteVeggplass(); rom[nr].settInn(inv); inv.neste = altInventar; altInventar = inv; } // Oppgave 6 (fortsettes her) // Her skal studentene vise at de kan starte en rekursiv metode. double totalForsikringsverdi() { if (altInventar == null) return 0; return altInventar.finnSummenAvForsikringsverdier(); } // Oppgave 8 4% // Her skal studentene vise at de kan bruke en egendefinert iterator. double totalForsikringsverdi2() { double tot = 0; for (Inventar inv: this) tot += inv.finnForsikringsverdi(); return tot; } // Oppgave 7 // I oppgave 7 skal studentene vise at de kan lage en iterator over en liste. public Iterator iterator() { return new InventarIterator(); } private class InventarIterator implements Iterator { Inventar denne = altInventar; public boolean hasNext() { return denne != null; } public Inventar next() { Inventar n = denne; denne = denne.neste; return n; } } // Testprogram // Det spørres ikke etter noe slikt i oppgavene. public static void main(String[] arg) { Skip titanic = new Skip(200); Rom salong = new Rom(200,60); titanic.rom[1] = salong; Rom spisesal = new Rom(200,60); titanic.rom[9] = spisesal; try { titanic.settInn(new EgetBilde("Nattverden", 100000000, 1490, 8.8), 1); titanic.settInn2(new EgetBilde("Skrik", 25000000, 1893, 0.735), 1); titanic.settInn2(new EgetBildeMobel("Orgel", 8500000, 1988, 8, 10), 9); } catch (ForLiteGulvplass g) { System.out.println("For lite gulvplass!"); } catch (ForLiteVeggplass g) { System.out.println("For lite veggplass!"); } System.out.println("Forsikringsverdi 1: " + titanic.totalForsikringsverdi()); System.out.println("Forsikringsverdi 2: " + titanic.totalForsikringsverdi2()); } } // Oppgave 5 (fortsettes) class ForLiteGulvplass extends Exception {} class ForLiteVeggplass extends Exception {} // Oppgave 3 (fortsettes) // Klassen Rom må inneholde en beholder fra Java-biblioteket (f.eks. ArrayList), // riktige instansvariable og riktig konstruktør. // // Notat: Oppgaveteksten her om standardverdier for areal og bredde kan lett // misforstås; i hvert tyder på spørsmålene under eksamen på det. Tanken er at // standardverdiene skal brukes når man oppretter Rom-objekter. // Misforståelser på dette punktet bør bedømmes mildt. class Rom { double maxAreal, maxBredde, bruktAreal, bruktBredde; ArrayList inventar = new ArrayList<>(); Rom(double ar, double br) { maxAreal = ar; bruktAreal = 0; maxBredde = br; bruktBredde = 0; } // Oppgave 4 (fortsettes) void settInn(Inventar inv) { inventar.add(inv); if (inv instanceof Mobel) bruktAreal += ((Mobel)inv).areal(); if (inv instanceof Bilde) bruktBredde += ((Bilde)inv).bredde(); } // Oppgave 5 (fortsettes) boolean ledigAreal(double ar) { return ar <= maxAreal-bruktAreal; } boolean ledigBredde(double br) { return br <= maxBredde-bruktBredde; } }