LO191D/LC191D Videregående programmering Eksamen mai 2012 Løsningsforslag Oppgave 1 Klassen Destinasjon: // Oppgaven er uklar på hva som skal inn i klassen Destinasjon. // Her følger en minimumsutgave (klassen utvides i oppgave 2) class Destinasjon { private final String navn; private ArrayList<Utflukt> utflukter = new ArrayList<Utflukt>(); public Destinasjon(String navn) { this.navn = navn; public String getnavn() { return navn; Klassen Utflukt: abstract class Utflukt { /* SOM GITT I OPPGAVETEKSTEN */ public int finnantbusser() { // returnerer 0 hvis for få påmeldte return beregnantbusser(finnantpåmeldte()); public int finnantpåmeldte() { return deltakere.size(); public boolean reserverplass(passasjer[] pass) { for (int i = 0; i < pass.length; i++) { deltakere.add(pass[i]); return true; 1
// Metoden lages static med antpers som parameter, da kan den brukes i flere sammenhenger. static protected int beregnantbusser(int antpers) { if (antpers < MIN_ANTALL) { return 0; else { int anthelebusser = antpers / ANT_PR_BUSS; if (antpers % ANT_PR_BUSS > 0) { anthelebusser++; return anthelebusser; Klassen UtfluktMedSetebest: class UtfluktMedSetebest extends Utflukt { private String[][] seter; public UtfluktMedSetebest(String navn, Destinasjon dest, String beskrivelse, String starttid, String slutttid, double pris, int antrader, int antprrad) { super(navn, dest, beskrivelse, starttid, slutttid, pris); seter = new String[antRader][antPrRad]; // Bruker arvet utgave av finnantbusser(), skal derfor ikke programmene denne metoden her @Override public boolean reserverplass(passasjer[] pass) { if (finnseter(pass)) { // metoden finnseter() er gitt super.reserverplass(pass); return true; else { return false; private boolean finnseter(passasjer[] pass) { // SKAL IKKE PROGRAMMERES AV STUDENTENE // sjekker om det er plass og legger i tilfelle inn passasjernavn i sete-tabellen return true; Klassen UtfluktMedGuide: // Kan med fordel bruke ENUM for språk, men dette er ikke eksamenspensum. 2
// En kan også lage en klasse med språk og antall, og så lage en tabell med objekter av denne klassen. // Kan også kombinere de to løsningene i en «enum-klasse». class UtfluktMedGuide extends Utflukt { public final static String[] SPRÅK = {"norsk", "engelsk", "tysk", "fransk", "spansk"; private int[] antprspråk = new int[språk.length]; public UtfluktMedGuide(String navn, Destinasjon dest, String beskrivelse, String starttid, String slutttid, double pris, int antrader, int antprrad) { super(navn, dest, beskrivelse, starttid, slutttid, pris); @Override public boolean reserverplass(passasjer[] pass) { for (int i = 0; i < pass.length; i++) { antprspråk[finnindeksspråk(pass[i].getspråk())]++; return super.reserverplass(pass); private int finnindeksspråk(string språk) { for (int i = 0; i < SPRÅK.length; i++) { if (SPRÅK[i].equalsIgnoreCase(språk)) { return i; return -1; // skal ikke komme hit @Override public int finnantbusser() { int antbusser = 0; for (int i = 0; i < SPRÅK.length; i++) { antbusser += beregnantbusser(antprspråk[i]); return antbusser; Klassen SelvstUtflukt: class SelvstUtflukt extends Utflukt { private int antpåmeldte = 0; public SelvstUtflukt(String navn, Destinasjon dest, String beskrivelse, String starttid, String slutttid, double pris) { super(navn, dest, beskrivelse, starttid, slutttid, pris); 3
// Bruker arvede utgaver av begge metodene i oppgaven, // skal derfor ikke programmere noen av dem her. Oppgave 2 1. Klassen Cruiseskip: public int finnantbusser(string destnavn) { int sum = 0; for (Destinasjon d : destinasjoner) { if (d.getnavn().equals(destnavn)) { sum += d.finnantbusser(); return sum; Utvider klassen Destinasjon: public int finnantbusser() { int sum = 0; for (Utflukt u : utflukter) { sum += u.finnantbusser(); return sum; 2. Klassen Cruiseskip: public ArrayList<Integer> registrerpåmeldinger(int[] kundenr, Utflukt utflukt) { Passasjer[] passasjerliste = new Passasjer[kundenr.length]; ArrayList<Integer> indeksknrikkefunnet = new ArrayList<Integer>(); for (int i = 0; i < kundenr.length; i++) { int indeks = søkindeksgittknr(kundenr[i]); // gyldig kundenr? if (indeks >= 0) { passasjerliste[i] = passasjerer.get(indeks); passasjerliste[i].registrerutflukt(utflukt); // aggregering fra Passasjer til Utflukt else { indeksknrikkefunnet.add(i); utflukt.reserverplass(passasjerliste); // aggregering fra Utflukt til Passasjer if (indeksknrikkefunnet.size() == 0) { return null; else { return indeksknrikkefunnet; 4
private int søkindeksgittknr(int knr) { // Hjelpemetode for (int i = 0; i < passasjerer.size(); i++) { Passasjer p = passasjerer.get(i); if (p.getkundenr() == knr) { return i; return -1; Ny metode i klassen Passasjer: void registrerutflukt(utflukt utflukt) { utflukter.add(utflukt); Oppgave 3 Oppgaven er løst ved å lage klassen Sete, som er en subklasse til JButton. class Gui extends JFrame { private Sete[][] setene; // en trykknapp for hvert sete private String[][] setenavn; private String[] navn; // de som skal reservere seter private GuiSal sal; private JButton reserverknapp = new JButton("Reserver"); public Gui(String[][] setenavn, String[] navn) { this.navn = navn; // ingen beskyttelse av data this.setenavn = setenavn; // ingen beskyttelse av data setene = new Sete[setenavn.length][setenavn[0].length]; sal = new GuiSal(); setdefaultcloseoperation(jframe.exit_on_close); settitle("setereservasjon"); setlayout(new BorderLayout(5, 5)); add(sal, BorderLayout.CENTER); add(reserverknapp, BorderLayout.SOUTH); reserverknapp.addactionlistener(new ReserverLytter()); 5
pack(); private class ReserverLytter implements ActionListener { public void actionperformed(actionevent hendelse) { int antreservert = 0; for (int rad = 0; rad < setene.length; rad++) { for (int setepårad = 0; setepårad < setene[0].length; setepårad++) { if (setene[rad][setepårad].erforeløpigreservert()) { antreservert++; if (antreservert!= navn.length) { showmessagedialog(null, "Feil antall reserverte plasser. Du har reservert " + antreservert + ", du har bedt om " + navn.length + "."); else { int resnr = 0; for (int rad = 0; rad < setene.length; rad++) { for (int setepårad = 0; setepårad < setene[0].length; setepårad++) { if (setene[rad][setepårad].erforeløpigreservert()) { setene[rad][setepårad].foretapermanentreservasjon(navn[resnr]); setenavn[rad][setepårad] = navn[resnr]; resnr++; showmessagedialog(null, "Reservasjoner ok."); private class GuiSal extends JPanel { public GuiSal() { setlayout(new GridLayout(setenavn.length, setenavn[0].length, 5, 5)); int antledige = 0; for (int rad = 0; rad < setenavn.length; rad++) { for (int setepårad = 0; setepårad < setenavn[0].length; setepårad++) { setene[rad][setepårad] = new Sete(rad, setepårad, setenavn[rad][setepårad]); if (setenavn[rad][setepårad] == null) { antledige++; add(setene[rad][setepårad]); 6
if (antledige < navn.length) { showmessagedialog(null, "Ikke nok ledige plasser. Du prøver å reservere " + navn.length + ", det er kun " + antledige + " ledige plasser."); pack(); private class Sete extends JButton { private final Color OPPTATT = Color.PINK; // ikke mulig å bruke static i indre klasser private final Color LEDIG = Color.WHITE; private final Color RESERVERT = Color.LIGHT_GRAY; private String navn = null; private final int rad; private final int setepårad; public Sete(int rad, int setepårad, String navn) { this.rad = rad; this.setepårad = setepårad; this.navn = navn; settext("" + (rad + 1) + ", " + (setepårad + 1)); if (navn == null) { setbackground(ledig); else { setbackground(opptatt); setenabled(false); addactionlistener(new Setelytter()); public boolean erforeløpigreservert() { return (getbackground() == RESERVERT); public boolean erpermanentreservert() { return (getbackground() == OPPTATT); public void foretapermanentreservasjon(string navn) { setbackground(opptatt); setenabled(false); this.navn = navn; 7
private class Setelytter implements ActionListener { public void actionperformed(actionevent hendelse) { if (getbackground() == LEDIG) { setbackground(reservert); else if (getbackground() == RESERVERT) { setbackground(ledig); else { System.out.println("FEIL OPPSTÅTT"); 8