AVDELING FOR INGENIØRUTDANNING

EKSAMENSOPPGAVE

Emne:
PROGRAMMERING
Emnekode:
LO 125 A
Faglig veileder:
Eva Vihovde
Grupper:
1AA, 1AB, 1AC, 1IA, 1IB, 1IC, A (ØKS)
Dato:
12.12.2003
Eksamenstid:
09.00 - 14.00
Eksamensoppgaven består av:   Antall sider (inkl. forsiden): 8  Antall oppgaver: 5 Antall vedlegg: 0 
Tillatte hjelpemidler:   Alle trykte og håndskrevne
Kandidaten må selv kontrollere at oppgavesettet er fullstendig. Ved eventuelle uklarheter i oppgaveteksten skal du redegjøre for de forutsetninger du legger til grunn for løsningen.

Les gjennom hele oppgavesettet før du begynner å besvare deloppgavene.

 

Utarbeidet av (faglærer): Kontrollert av (en av disse): Studieleders/
Fagkoordinators underskrift:
Annen lærerSensorStudieleder/
Fagkoordinator
  
 
   

SKIHEIS

I denne oppgaven skal du lage deler av et program som simulerer billettsystemet til skiheisene på et skisenter. Med enkle modifikasjoner kan systemet anvendes på mange tilsvarende problemstillinger der man enten betaler pr. gang, pr. dag, pr. måned eller pr. år, som f.eks ved bomstasjoner, på et treningstudio eller liknende.

Programmet skal ha en modul som simulerer billettkontrollen, og en annen for blant annet salg av forskjellige typer heiskort. De enkelte deloppgavene inneholder nærmere informasjon.

Oppgave 1

For hver tur i skiheisen må skiløperen/alpinisten passere billettkontrollen med gyldig heiskort. Kortet er enten et klippekort, et dagskort eller et årskort. (Vi har av hensyn til oppgavens kompleksitet valgt årskort istedenfor sesongkort som ville vært mer realistisk.) Du skal i denne deloppgaven lage en abstrakt superklasse Kort. Klassen skal innholde de data og metoder som er felles for alle typer heiskort, blant annet:

   kortNr  // et unikt nummer som identifiserer hvert enkelt kort
   pris    // hva kortet koster i hele kroner.

Klassen skal ha en konstruktør for nødvendig initialisering av instansvariablene/datafeltene.

HINT: For å generere unike nummer til hvert kort kan det være lurt å bruke en static variabel som økes med én for hvert kort som blir generert.

Videre skal klassen ha aksess-metoder (get-metoder) som returnerer verdiene til henholdsvis kortNr og pris.

Resten av metodene skal være abstrakte:

  public abstract boolean passering();
  public abstract boolean gyldig();

og skal følgelig implementeres senere.

a) Programmer klassen Kort.

***

De neste to deloppgavene går ut på å programmere metoder i klassen Klippekort. Nedenfor finner du en skisse av denne klassen:

public class Klippekort extends Kort
{
   public static final int PRIS_PER_KLIPP = 20;
   private int antallKlipp;   // antall klipp som til enhver tid er igjen på kortet

   private static int antallSolgte = 0; // Det totale antall solgte klippekort
   private static int sum = 0;  // Den totale summen det er solgt klipp for
                                // på alle klippekortene til sammen.

   < konstruktør >
   < metoder >
}

b)
Programmer klassens konstruktør. Som parameter skal kontruktøren ta imot informasjon om hvor mange klipp kortet inneholder som nytt. Foruten å sørge for å initialisere klassens instansvariable/datafelt, skal konstruktøren også sørge for å oppdatere antall solgte klippekort og ikke minst summen det er solgt klippekort for så langt.

Videre skal du i denne deloppgaven programmere aksess-metoder (get-metoder) for static-variablene antallSolgte og sum.

c)
Du skal i denne deloppgaven programmere tre metoder:

   public void ladOpp( int n ) { ... }

Metoden over skal øke antall klipp på kortet med det antallet som parameteren n angir og oppdatere summen det er solgt klipp for.

   public  boolean gyldig() { ... }

Metoden over skal returnere true hvis kortet er gyldig og i motsatt fall false.

   public boolean passering() { ... }

Metoden over skal registrere en tur i skiheisen, under forutsetning av at kortet er gyldig. Returverdien skal fortelle om passeringen av billettkontrollen var vellykket.

***

To av korttypene, dagskort og årskort, er avhengig av å lagre henholdsvis dagen og året kortene blir solgt. I pakken java.util finner vi klassen Calendar, og i den de metodene vi trenger for å få tak i dagen og året vi står i ved hjelp av følgende setninger:

  int dag = Calendar.getInstance().get( Calendar.DAY_OF_YEAR );
  int år = Calendar.getInstance().get( Calendar.YEAR );

d)
Nedenfor ser du en skisse av klassen Årskort:

public class Årskort extends Kort
{
   public final static int ÅRSPRIS = 3000;
   private int år;	// Året kortet gjelder for
   private String navn;   // Eierens navn
   private static int antallSolgte = 0; // Det totale antall solgte årskort
   private static int sum = 0;	  // Den totale summen det er solgt årskort for

   < konstruktør >
   < aksess-metoder / get-metoder >
   < metoder du skal programmere >
}

Programmer klassens konstruktør. Konstruktøren mottar navnet på eieren av kortet som parameter og skal sørge for å initialisere og oppdatere klassens instansvariable/datafelt.

Programmer metoden

   public boolean gyldig() { ... }

Metoden over skal kun undersøke om vi befinner oss i riktig år ut fra det året kortet gjelder for. Returverdien skal samsvare med resultatet.

Kortet er personlig, og enkelte ganger vil det ved billettkontrollen bli sjekket om brukeren av kortet er eieren av kortet. I denne forbindelse skal du programmere metoden

   public boolean passering(String navn) { ... }

Metoden over registrerer en passering av billettkontrollen under forutsetning av at kortet er gyldig og at navnet som parameteren angir også er navnet på eieren av kortet. Returverdien skal fortelle om personen passerte billettkontrollen eller ikke.

Eierens identitet blir imidlertid ikke sjekket ved hver passering, så du skal også programmere metoden

   public boolean passering() { ... }

som kun registrerer en passering under forutsetning av at kortet er gyldig. Returverdien skal fortelle om personen passerte billettkontrollen eller ikke.

Du skal ikke programmere aksess-metodene/ get-metodene da disse stort sett blir like dem du programmerte under punkt b. Men det er viktig at du bruker dem der du finner det hensiktsmessig.

***

Til slutt i oppgave 1 ser du en skisse over klassen Dagskort. Du skal ikke programmere noe i denne klassen, men vite at du har den og merke deg hvilke metoder den har slik at du kan bruke den der du finner det nødvendig:

public class Dagskort extends Kort
{
   public final static int DAGSPRIS = 200;
   private int dag;
   private static int sum = 0;
   private static int antallSolgte = 0;

   < konstruktør >
   < aksess-metoder / get-metoder >

   public boolean gyldig() { ... }
   public boolean passering() { ... }
}

Oppgave 2

Klassen Kortsystem, som er skissert nedenfor, skal lagre heiskortene. I utgangspunktet er det plass til 100 heiskort. Arrayens størrelse skal imidlertid kunne økes etter behov slik at salg av heiskort ikke begrenses til 100.

public class Kortsystem
{
  public static final int MAX = 100;
  public static final int UTVIDELSE = 10;
  public static final int KLIPPEKORT = 0, DAGSKORT = 1, ÅRSKORT = 2;
  private Kort[] kortArray;

  public Kortsystem()
  {
    kortArray = new Kort[MAX];
  }

   < metoder du skal programmere >
}

a)
Programmer metoden

   public void utvidArray() { ... }

Metoden skal utvide arrayen med så mange elementer som konstanten UTVIDELSE angir. Metoden vil bli kalt når det er behov for å utvide arrayen i forbindelse med innsetting av et nytt heiskort.

b)
Programmer metoden

   public void settInnKort(Kort k) { ... }

Metoden mottar et nytt heiskort som parameter og skal sette dette inn på første ledige plass i arrayen. Hvis arrayen er full, må du først utvide den med så mange elementer som konstanten UTVIDELSE angir, og deretter sette inn kortet.

c)
Under denne deloppgaven skal du programmere følgende to metoder

   public Kort finnKort(int nr) { ... }

som returnerer en referanse til heiskortet med kortNr lik den innkomne parameteren nr. Hvis kortet ikke finnes i arrayen, skal metoden returnere null.

   public void fjernUgyldigeKort() { ... }

Metoden over skal fjerne alle ugyldige kort fra arrayen, det vil si kort som er gått ut på dato, eller klippekort der alle klippene er brukt opp.

d)
Eieren av et klippekort skal ha mulighet til å "lade opp" kortet med et visst antall klipp. Programmer metoden

   public boolean ladOppKort(int nr, int antall) { ... }

Metoden skal øke antall klipp på kortet med kortNr lik den innkomne parameteren nr, med det antall klipp som den innkomne parameteren antall angir. Hvis dette lar seg gjøre, skal metoden returnere true, og i motsatt fall skal den returnere false.

e)
Kortsystemet skal ha mulighet for å skrive ut informasjon om hvor mange kort det er solgt av de forskjellige typene, hvor mye som er tjent inn på hver type, og hvor mye som er tjent inn totalt. Programmer metoden

   public String inntjeningsInfo() { ... }

Oppgave 3

Billettsystemets display for billettkontroll er vist på bildet under.

Vinduet er definert i klassen BillettKontroll som du finner en skisse av nedenfor:

< import-setninger >

public class BillettKontroll extends JFrame
{  private JTextField kortNrFelt, navneFelt, display;
   private JButton kontroll;
   private Kortsystem kortsystem;

   public BillettKontroll(Kortsystem k)
   { super("BILLETT-KONTROLL");
     kortsystem = k;
     :
     :
     kontroll = new JButton("Billett-kontroll");
     kontroll.addActionListener(new ActionListener()
             { public void actionPerformed(ActionEvent e)
               {  kontrollerKort();
               }
             });

    < oppretter resten av brukergrensesnittet >
   }

   public void kontrollerKort()  { ... }
}

a)
Metoden du skal programmere i denne oppgaven skal kalles ved billett-kontroll:

   public void kontrollerKort()  { ... }

Metoden må lese inn kortets nummer og sjekke at kortet er gyldig, under forutsetning av at det finnes, og eventuelt registrere en passering (ved klippekort). Hvis kortet er gyldig, skrives "OK" i diplay-vinduet, i motsatt fall "STOPP". Hvis kortet er et årskort, skal metoden sjekke om brukeren av programmet har skrevet inn et navn i navnefeltet, og i så fall foreta en billettkontroll som også sjekker navnet. Metoden skal sørge for å blanke ut navnet i navnefeltet etter at kontrollen er foretatt. Hvis det ikke står noe i navnefeltet, skal det bare sjekkes om kortet er gyldig.

TIL ORIENTERING: For å få skrevet ut "OK" og "STOPP" med fontene som vist på bildet med sentrering av teksten midt på displayet og med bakgrunnsfargene rød eller grønn, er det brukt følgende programsetninger:

   display.setFont(new Font("Times", Font.BOLD, 60));
   display.setBackground( Color.RED); // ev. Color.GREEN
   display.setHorizontalAlignment(display.CENTER);

Oppgave 4

Vinduet under brukes ved salg av heiskort, opplading av klippekort og til å hente informasjon om salg av kort med mer.

Vinduet er definert i klassen Kortsalg som du finner en skisse av nedenfor:

< import-setninger >

public class Kortsalg extends JFrame
{  private static final int KLIPP = 1, DAG = 2, ÅR = 3;
   private JTextField kortNrFelt, navneFelt, betalingsFelt, antallKlippFelt;
   private JButton klipp, dag, år, infoknapp, fjern, ladeknapp;
   private JTextArea info, display;
   private Lytter lytter;
   private Kortsystem kortsystem;

   public Kortsalg(Kortsystem k)
   { super("KORTSALG");
     kortsystem = k;
     lytter =  new Lytter();
     :
     < oppretter resten av brukergrensesnittet >
     :
     klipp.addActionListener(lytter);
     dag.addActionListener(lytter);
     år.addActionListener(lytter);
     ladeknapp.addActionListener( lytter );
   }

   < metoder du skal programmere >

   private class Lytter ... { ... }
}

a)
Programmer metoden

   public void selgKort(int type) { ... }

Metoden skal foreta et salg av et heiskort av typen parameteren type angir. (Se konstantene i skissen av klassen over.) Når kortet er opprettet og satt inn i datasystemet, skal metoden skrive ut kortets nummer i tekstfeltet kortNrFelt og prisen som skal betales i tekstfeltet betalingsFelt.

b)
Programmer metoden

   public void ladOppKort() { ... }

Metoden skal lade opp klippekortet med det antall klipp som brukeren skriver inn, under forutsetning av at nummeret brukeren skriver inn tilhører et klippekort i datasystemet. Hvis dette går bra, skal det skrives en melding om det i displayet og prisen som skal betales skrives i betalingsfeltet. I motsatt fall skal det gis melding om at klippekort med dette nummer ikke finnes.

c)
I denne deloppgaven skal du programmere to metoder:

   public void salgsinformasjon() { ... }

som skriver ut på displayet hvor mange kort det er solgt av de forskjellige typene, hvor mye som er tjent inn på hver type, og hvor mye som er tjent inn totalt.

   public void fjernUgyldigeKort() { ... }

som sørger for at alle ugyldige kort blir fjernet fra datasystemet, det vil si kort som er gått ut på dato når metoden blir kalt, eller klippekort der alle klippene er brukt opp.

d)
Programmer den private lytteklassen

   private class Lytter ... { ... }

slik at den fanger opp hendelsene som brukeren av programmet genererer og utfører de tilhørende operasjonene.






Oppgave 5

Lag klassen KortApplikasjon som inneholder hovedprogrammet. Dette skal opprette et synlig vindu av hver av typene du har programmert og starte hele applikasjonen. Programmer lukkeknappene på vinduene slik at applikasjonen avsluttes når vinduene lukker seg.

SLUTT!