Add rest
@@ -2,12 +2,12 @@
|
||||
|
||||
Denne mappen inneholder øvingstekster for TDT4100 - Objektorientert programmering våren 2021. Tabellen under inneholder linker til hver enkelt oppgavetekst og tema for øvingen. Linker vil bli oppdatert underveis.
|
||||
|
||||
| Øving | Tema |
|
||||
| ----------------- | ---------------------------------------- |
|
||||
| Øving | Tema |
|
||||
| --------------------------- | ---------------------------------------- |
|
||||
| [Øving 1](oving1/README.md) | Tilstand og oppførsel |
|
||||
| Øving 2 | Innkapsling og validering |
|
||||
| Øving 3 | Klasser og testing |
|
||||
| Øving 4 | Objektstrukturer |
|
||||
| Øving 5 | Grensesnitt |
|
||||
| Øving 6 | Observatør-observert og delegering |
|
||||
| Øving 7 | Arv og abstrakte klasser |
|
||||
| [Øving 2](oving2/README.md) | Innkapsling og validering |
|
||||
| [Øving 3](oving3/README.md) | Klasser og testing |
|
||||
| [Øving 4](oving4/README.md) | Objektstrukturer |
|
||||
| [Øving 5](oving5/README.md) | Grensesnitt |
|
||||
| [Øving 6](oving6/README.md) | Observatør-observert og delegering |
|
||||
| [Øving 7](oving7/README.md) | Arv og abstrakte klasser |
|
||||
|
||||
18
oppgavetekster/classpath_fix/README.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Fiks ved problemer med å pulle i Eclipse
|
||||
|
||||
Dersom du får problemer med å pulle øvinger i Eclipse, med feilmelding som vist i bildet under ("Checkout conflict with files: `<prosjektnavn>/.classpath`), kan du følge denne guiden for å løse problemet.
|
||||
|
||||
**NB!** Bildene i denne guiden går ut i fra at problemfilen ligger i `ovinger`-prosjektet, men det kan også være under et av de andre prosjektene.
|
||||
Du kan se hvilke filer som er problematiske i feilmeldinga du får når du puller.
|
||||
|
||||

|
||||
|
||||
| Beskrivelse | Bilde |
|
||||
|------|-------|
|
||||
| I Project-explorer i Eclipse, trykk på de tre prikkene i øvre høyre hjørne. I menyen som kommer opp velger du *Filters and Customization...* (I MacOS står det kun *Filters...*). |   |
|
||||
| I vinduet som kommer opp, pass på at valget `.* resources` **IKKE** er valgt, og trykk ok. |  |
|
||||
| Åpne prosjektet du hadde konflikter i, dette er sannsynligvis ovinger. Du vil se at det har dukket opp en fil som heter `.classpath` under prosjektmappa. |  |
|
||||
| Høyreklikk på `.classpath`-fila, og velg *Replace With* -> *HEAD Revision*. Trykk *Discard Changes* i vinduet som kommer opp. | ) |
|
||||
| Nå kan du prøve å pulle igjen (høyreklikk på prosjektet og velg *Team* -> *Pull*). Sannsynligvis vil prosjektet nå se ganske kaotisk ut, med veldig mange mapper. Det fikser du enkelt ved å høyreklikke på det, og velge *Maven* -> *Update Project*, velge alle prosjektene, og trykke *OK* |  |
|
||||
|
||||
Etter denne prosessen skal alt fungere som før. Har du problemer, ta kontakt med undass.
|
||||
BIN
oppgavetekster/classpath_fix/img/1.png
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
BIN
oppgavetekster/classpath_fix/img/2.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
oppgavetekster/classpath_fix/img/3.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
oppgavetekster/classpath_fix/img/4.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
oppgavetekster/classpath_fix/img/5.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
oppgavetekster/classpath_fix/img/6.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
oppgavetekster/classpath_fix/img/7.png
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
oppgavetekster/classpath_fix/img/8.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
oppgavetekster/classpath_fix/img/9.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
@@ -1,7 +1,7 @@
|
||||
# Interface - CardContainer-oppgave
|
||||
Denne oppgaven handler om å lage et felles grensesnitt for `CardDeck`- og `CardHand`-klassene, laget i oppgavene
|
||||
[Innkapsling - Card-oppgave](../oving3/Card.md) og
|
||||
[Objektstrukturer - Card-oppgave del 2](../oving5/Card.md).
|
||||
[Objektstrukturer - Card-oppgave del 2](../oving4/Card.md).
|
||||
Her skal du lage og implementere et grensenitt kalt `CardContainer`, som spesifiserer metoder for lesing av samlinger av Card-objekter.
|
||||
|
||||
#### Del 1 - CardContainer interface
|
||||
|
||||
74
oppgavetekster/oving7/AbstractAccount.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# Arv - AbstractAccount-oppgave
|
||||
Denne oppgaven handler om å lage en felles abstrakt superklasse `AbstractAccount`
|
||||
for `CreditAccount`, `DebitAccount`- og `SavingsAccount2`-klassene.
|
||||
|
||||
Denne oppgaven er en annen variant av
|
||||
[SavingsAccount](./SavingsAccount.md)-oppgaven, med fokus
|
||||
på bruk av abstrakte klasser og arv.
|
||||
|
||||
### Del 1 - Abstrakt klasse AbstractAccount
|
||||
En bank består av mange ulike type kontoer: sparekontoer, brukskontoer,
|
||||
depositumskontoer, støttekontoer etc. Siden disse har mye felles, f.eks.
|
||||
har alle en balanse, så er det praktisk å samle så mye som mulig av den
|
||||
felles logikken i en superklasse, som alle kan arve fra. Denne superklassen
|
||||
er imidlertid ikke noen egen type konto, og derfor gjør vi den abstrakt,
|
||||
slik at den ikke kan instansieres. De konkrete konto-klassene som arver
|
||||
fra den, må selvsagt være instansierbare.
|
||||
|
||||
Metodene i `AbstractAccount`-klassen, er omtrent de samme som dem vi definerte
|
||||
i `Account`-grensesnittet i [SavingsAccount](./SavingsAccount.md)-oppgaven,
|
||||
og er som følger:
|
||||
|
||||
* `void deposit(double)` - øker kontobalansen med innskutt beløp. Merk at det
|
||||
innskutte beløpet må være positivt. Ved ulovlig innskudd skal en
|
||||
`IllegalArgumentException` utløses.
|
||||
* `void withdraw(double)` - Metoden kaller <code>internalWithdraw(<i>uttaksbeløp</i>)</code>,
|
||||
som implementeres i hver subklasse. Hvis uttaksbeløpet er negativt skal
|
||||
metoden utløse en `IllegalArgumentException`.
|
||||
* `abstract void internalWithdraw(double)` - minsker kontobalansen med beløpet
|
||||
som blir tatt ut. Merk at reglene for uttak er ulik for klassene som
|
||||
implementerer `AbstractAccount`, og må derfor implementeres i hver klasse.
|
||||
Hvis det ikke er mulig å ta ut det angitte beløpet skal metoden utløse en
|
||||
`IllegalStateException`.
|
||||
* `double getBalance()` - returnerer kontobalansen.
|
||||
|
||||
Alle metodene utenom den absktrakte må implementeres. I tillegg må
|
||||
`AbstractAccount` ha en tilstand *balance* for saldo på kontoen.
|
||||
Saldoen skal settes til 0 i konstruktøren.
|
||||
|
||||
Vær oppmerksom på at du i Del 2 skal lage subklasser av `AbstractAccount`
|
||||
og at du ved å bruke rett innkapsling (hint: `protected`-modifikatoren) skal
|
||||
la *subklassene* nyttiggjøre seg *superklassen* i størst mulig grad.
|
||||
|
||||
|
||||
### Del 2 - DebitAccount extends AbstractAccount
|
||||
En debetkonto er den enkleste formen for konto, hvor det eneste kravet er at
|
||||
saldoen til enhver tid må være større eller lik 0. `DebitAccount` skal utvide
|
||||
(arve fra med `extends`) `AbstractAccount` og sikre at saldoen aldri blir
|
||||
lavere enn 0.
|
||||
|
||||
Testkode for oppgavene finner du her: [inheritance/DebitAccountTest.java](../../src/test/java/inheritance/DebitAccountTest.java).
|
||||
|
||||
### Del 3 - CreditAccount extends AbstractAccount
|
||||
En `CreditAccount` har i tillegg til *balance* en tilstand for *creditLine*,
|
||||
altså tilgjengelig kreditt på kontoen. Denne kredittlinjen tillater at kontoen
|
||||
kan overtrekkes (at saldoen er negativ) innenfor kredittlinjen. Klassen må ha
|
||||
*tilgangsmetoder* (getters and setters) for *creditLine*. Merk at
|
||||
kredittlinjen alltid må være større eller lik 0, hvis ikke skal det utløses
|
||||
en `IllegalArgumentException`. Hvis en ny kredittlinje settes og balansen er
|
||||
negativ, må den nye kredittlinjen dekke den eksisterende balansen. Ellers skal
|
||||
det utløses en `IllegalStateException` og ingen endring i kredittlinjen.
|
||||
|
||||
Konstruktøren `CreditAccount(double)` skal sette kredittlinjen.
|
||||
|
||||
Testkode for oppgavene finner du her: [inheritance/CreditAccountTest.java](../../src/test/java/inheritance/CreditAccountTest.java).
|
||||
|
||||
### Del 4 - SavingsAccount2 extends AbstractAccount
|
||||
En `SavingsAccount2` (*merk at navnet er endret, for ikke å kræsje med
|
||||
SavingsAccount-klassen fra den tidligere oppgaven!*) kan kun ha positiv saldo.
|
||||
I tillegg har kontoen uttaksbegrensinger. En `SavingsAccount2` har *x* antall
|
||||
*uttak* (**withdrawals**). Dersom man ønsker å ta ut penger etter alle uttak er
|
||||
brukt opp, skal saldoen belastes med et *gebyr* (**fee**). Både **withdrawals**
|
||||
(antall) og **fee** (beløp) settes i konstruktøren `SavingsAccount2(int, double)`.
|
||||
|
||||
Testkode for oppgavene finner du her: [inheritance/SavingsAccount2Test.java](../../src/test/java/inheritance/SavingsAccount2Test.java).
|
||||
38
oppgavetekster/oving7/CardContainerImpl.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Arv - CardContainerImpl-oppgave
|
||||
|
||||
Denne oppgaven handler om å lage en felles superklasse `CardContainerImpl`
|
||||
for `CardDeck`- og `CardHand`-klassene, laget i [Card-oppgaven](../oving4/Card.md)
|
||||
og [CardContainer-oppgaven](../oving5/CardContainer.md).
|
||||
|
||||
**Merk:** Om du ikke har gjort Card-oppgaven og CardContainer-oppgaven allerede,
|
||||
kan du bruke løsningsforslaget som er lagt ut for disse under `lf/src/interfaces`.
|
||||
|
||||
### Del 1 - Superklassen CardContainerImpl
|
||||
Lag en `CardContainerImpl`-superklasse, som implementerer grensesnittet
|
||||
`CardContainer` (se [CardContainer-oppgaven](../oving5/CardContainer.md)) og
|
||||
inneholder koden som er felles for `CardDeck` og `CardHand`.
|
||||
|
||||
La `CardDeck` og `CardHand` arve `CardContainerImpl` og gjør nødvendige endringer
|
||||
i disse klassene, slik at totaloppførselen er som før. F.eks. skal `CardDeck`
|
||||
-objektet ha samme konstruktør som før, som skal sikre samme initielle tilstand
|
||||
(men ikke nødvendigvis med samme konstruktør-kode).
|
||||
|
||||
Merk at målet er at mest mulig kode skal flyttes til *superklassen* og gjenbrukes
|
||||
i *subklassene*. Det er viktig å bruke innkapsling rett
|
||||
(hint: `protected`-modifikatoren) for å nyttiggjøre seg superklassen i størst
|
||||
mulig grad.
|
||||
|
||||
### Del 2 - Regler for maksimalt antall kort
|
||||
Anta at en ønsker å unngå at instanser av `CardContainerImpl` (eller av en av
|
||||
subklassene) inneholder for mange kort. Legg til et *privat* `maxCardCount`-felt
|
||||
i `CardContainerImpl`, en konstruktør som *initialiserer* feltet og en *getter*
|
||||
for å lese verdien. Legg så til evt. endre kode i `CardContainerImpl` som sikrer
|
||||
at antall kort ikke overstiger dette tallet og at subklassene ikke kan omgå
|
||||
denne valideringen.
|
||||
|
||||
`CardContainerImpl`-subklassene `CardDeck` og `CardHand` skal sette maks-antallet
|
||||
som følger: `CardDeck` skal sette makstallet til *52* og `CardHand` skal ta
|
||||
inn maks-antallet i *sin* konstruktør. Hvis man forsøker å legge til flere kort
|
||||
enn hva som er tillatt i `CardHand`, skal det utløses en `IllegalStateException`.
|
||||
|
||||
Testkode for oppgavene finner du her: [inheritance/CardDeckTest.java](../../src/test/java/inheritance/CardDeckTest.java) og [inheritance/CardHandTest.java](../../src/test/java/inheritance/CardHandTest.java).
|
||||
140
oppgavetekster/oving7/ObservableList.md
Normal file
@@ -0,0 +1,140 @@
|
||||
# Observatør-observert-teknikken og arv - HighscoreList-oppgave med ObservableList
|
||||
Denne oppgaven handler om å bruke observatør-observert-teknikken for å bli
|
||||
informert om endringer i en highscore-liste. Vi bruker også arv for å skille
|
||||
ut gjenbrukbar kode for en generell, observerbar liste.
|
||||
|
||||
Observatør-observert-teknikken går ut på at det observerte objektet sier ifra
|
||||
til en eller flere observatører om at tilstanden er endret. I denne oppgaven
|
||||
skal vi lage en `HighscoreList` som kan si fra til lyttere av typen
|
||||
`ListListener` når nye resultater blir registrert. En hovedprogramklasse kalt
|
||||
`HighscoreProgram` vil bli brukt til å sjekke at det virker. Denne klassen
|
||||
oppretter en `HighscoreList`-instans, legger inn resultater (tall) fra
|
||||
konsollet som legges til lista og skriver ut lista hver gang et nytt resultat
|
||||
faktisk blir lagt til.
|
||||
|
||||
Klassene skal legges i `src/main/java/patterns.observable/` og tilhørende
|
||||
tester ligger i `src/test/java/patterns.observable/`.
|
||||
|
||||
### Del 1: Implementasjon av ObservableList og ObservableHighscoreList
|
||||
En `ObservableHighscoreList` skal holde styr på heltallsresultater (av typen
|
||||
int/Integer). Lista skal være *observerbar* ved at den kan registrere lyttere
|
||||
(`ObservableListListener`-instanser) og si fra til dem når lista blir endret.
|
||||
Lista skal ha en maksimal lengde, som settes i *konstruktøren*, f.eks. skal en
|
||||
topp 10-liste kunne opprettes med `new ObservableHighscoreList(10)`.
|
||||
Nye resultater registreres med metoden `addResult(int)`, som skal finne riktig
|
||||
posisjon og legge resultatet inn (dersom det er godt nok). Dersom lista er for
|
||||
lang, så skal det dårligste resultatet fjernes. NB: *Lavest verdi er best*,
|
||||
f.eks. antall sekunder på en oppgave eller antall flytt i Sokoban.
|
||||
|
||||
`ObservableListListener`-grensesnittet er vist i klassediagrammet nedenfor og
|
||||
må implementers av alle klasser som ønsker å fungere som lyttere for
|
||||
`ObservableHighscoreList`-instanser. Lyttere registrerer seg med
|
||||
`ObservableHighscoreList` sin `addObservableListListener`-metode og vil siden
|
||||
få beskjed om nye resultater ved at `listChanged`-metoden kalles. Argumentene
|
||||
som tas inn er `ObservableHighscoreList`-objektet som ble endret og *posisjonen*
|
||||
i lista der endringen skjedde.
|
||||
|
||||
Merk at første argument til `listChanged`-metoden er av typen `ObservableList`.
|
||||
Dette er en abstrakt superklasse for `ObservableHighscoreList`, som først
|
||||
brukes i del 3 og som da skal holde orden på lista. `ObservableList` vil ha en
|
||||
del generelle metoder som `ObservableHighscoreList` arver og kan bruke. For å
|
||||
kunne kjøre testene for `ObservableHighscoreList` allerede i del 1, så må
|
||||
`ObservableList` være definert fra starten. Lag derfor en tom
|
||||
`ObservableList`-klasse og bruk denne som superklasse for
|
||||
`ObservableHighscoreList`.
|
||||
|
||||
Her er en oversikt over metoden som må implementeres:
|
||||
|
||||
* `ObservableHighscoreList(int maxSize)` - konstruktøren tar inn *maks antall*
|
||||
resultater som lista skal kunne holde. Denne verdien må brukes av `addResult`,
|
||||
slik at resultater som er for dårlige kastes.
|
||||
* `size()` - returnerer antall elementer i lista, som altså aldri skal
|
||||
overstige maks-antallet
|
||||
* `int getElement(int)` - returnerer resultatet i posisjonen angitt av
|
||||
argumentet
|
||||
* `void addResult(int)` - registrere et nytt resultat, og dersom resultatet er
|
||||
godt nok til å komme med på lista, så legges det inn på riktig plass.
|
||||
Dersom lista blir for lang, så må dårligste resultat kastes. Alle registrerte
|
||||
lyttere må få beskjed om en evt. endring av lista, inkludert hvilken
|
||||
posisjon som ble endret.
|
||||
* `addObservableListListener(ObservableListListener)` - registrerer en ny lytter
|
||||
* `removeObservableListListener(ObservableListListener)` - fjerner en tidligere
|
||||
registrert lytter
|
||||
|
||||
Klassediagram for `HighscoreList`, `ListListener` og `ObservableList`:
|
||||
<img src="images/ObservableList_del1.png" width="570">
|
||||
|
||||
Testkode for denne oppgaven finner du her: [patterns/observable/ObservableHighscoreListTest.java](../../src/test/java/patterns/observable/ObservableHighscoreListTest.java).
|
||||
|
||||
### Del 2: Hovedprogram ObservableHighscoreListProgram
|
||||
Lag en hovedprogramklasse kalt `ObservableHighscoreListProgram`, som tester at
|
||||
`ObservableHighscoreList`-klassen din virker som den skal. La den opprette en
|
||||
`ObservableHighscoreList`-instans, lese inn tall fra konsollet (f.eks. med en
|
||||
`Scanner` og `nextInt`-metoden) og legge disse inn i lista. Sørg for at
|
||||
`ObservableHighscoreListProgram` implementerer
|
||||
`ObservableListListener`-grensesnittet og registrerer seg som lytter på
|
||||
`HighscoreList`-instansen. La lyttermetoden `listChanged` skrive ut informasjon
|
||||
og resultatene i `HighscoreList`-instansen og posisjonsargumentet, slik at du
|
||||
ser at alt virker som det skal.
|
||||
|
||||
Vi foreslår følgende metoder og oppførsel:
|
||||
|
||||
* `void init()` - oppretter en ny `ObservableHighscoreList` og registrerer seg
|
||||
selv (altså `ObservableHighscoreListProgram`-instansen) som lytter
|
||||
* `void run()` - leser inn tall (resultater) fra konsollet og legger dem til i
|
||||
listen
|
||||
* `void listChanged(ObservableList, int)` - observerer endringer i
|
||||
`ObservableHighscoreList`-instansen og skriver ut posisjonsargumentet, samt
|
||||
selve listen, til konsollet
|
||||
|
||||
Klassediagrammet viser hvordan klassene henger sammen, og vårt forslag til
|
||||
metoder:
|
||||
<img src="images/ObservableList_del2.png" width="670">
|
||||
|
||||
### Del 3: ObservableList
|
||||
Den abstrakte superklassen `ObservableList` skal legges til som en generell
|
||||
superklasse for observerbare lister, som `ObservableHighscoreList` skal arve
|
||||
fra. Denne klassen skal både holde en liste med objekter (`Object`) og håndtere
|
||||
registrering av lyttere, altså en liste med `ObservableListListener`-instanse,
|
||||
som får beskjed om endringer i lista (slik at lista dermed er *observerbar*).
|
||||
Dette betyr at `ObservableList` overtar håndtering av både resultater og
|
||||
lyttere fra `ObservableHighscoreList`-klassen. For å gjøre `ObservableList` mer
|
||||
generell og gjenbrukbar, så lar vi den håndtere `Object`-instanser (heller enn
|
||||
`Integer`). Samtidig deklarerer den en *abstrakt* metode `acceptsElement`, som
|
||||
subklasser må *redefinere* for å bestemme hva slags objekter det skal være lov
|
||||
å legge inn. `ObservableHighscoreList` vil f.eks måtte redefinere den slik
|
||||
at bare `Integer`-objekter aksepteres.
|
||||
|
||||
`ObservableList` skal ha følgende metoder (noen er altså overtatt fra
|
||||
`ObservableHighscoreList`):
|
||||
|
||||
* `int size()` - returnerer antall elementer i lista
|
||||
* `Object getElement(int)` - returnerer elementet i posisjonen angitt av
|
||||
argumentet
|
||||
* `abstract boolean acceptsElement(Object)` - returnerer hvorvidt *subklassen*
|
||||
aksepterer at objektet legges inn i lista (f.eks. aksepterer `HighscoreList`
|
||||
kun `Integer`-objekter).
|
||||
* `void addElement(int, Object)` - legger til et element på posisjonen angitt
|
||||
av argumentet, men bare dersom det *aksepteres* som element. Dersom elementet
|
||||
ikke aksepteres, så skal `IllegalArgumentException` utløses. Dersom posisjonen
|
||||
er ulovlig så skal `IndexOutOfBoundsException` utløses.
|
||||
* `void addElement(Object)` - legger til et element bakerst i lista, men bare
|
||||
dersom det *aksepteres* som element. Dersom elementet ikke aksepteres, så skal
|
||||
`IllegalArgumentException` utløses.
|
||||
* `void removeElement(int)` - fjerner elementet på posisjonen angitt av
|
||||
argumentet. Dersom posisjonen er ulovlig så skal `IndexOutOfBoundsException`
|
||||
utløses.
|
||||
|
||||
`ObservableHighscoreList` skal endres slik at den i størst mulig grad bruker
|
||||
metodene som arves fra `ObservableList`, men forøvrig ikke endrer oppførsel.
|
||||
Kjør hovedprogramklassen `ObservableHighscoreListProgram` for å sjekke at dette
|
||||
faktisk stemmer.
|
||||
|
||||
Klassediagrammet viser hvordan klassene henger sammen, og hvor metodene nå er
|
||||
deklarert/implementert. Merk at `addElement`- og `removeElement`-metodene er
|
||||
angitt som `protected` (ruter-symbolet), slik at kun subklasser skal kunne
|
||||
bruke dem.
|
||||
<img src="images/ObservableList_del3.png" width="670">
|
||||
|
||||
Testkode for denne oppgaven finner du her: [patterns/observable/ObservableListTest.java](../../src/test/java/patterns/observable/ObservableListTest.java).
|
||||
|
||||
40
oppgavetekster/oving7/README.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# Øving 07: Arv og abstrakte klasser
|
||||
|
||||
**Øvingsmål**
|
||||
* Lære hvordan arv-mekansimen brukes i OO
|
||||
* Lære om instanser, typer, deklarasjoner og tilordninger
|
||||
* Lære om sub- og superklasser samt om synlighetsmodifikatorer som brukes ved arv
|
||||
* Lære om abstrakte klasser, deres bruksområder og fordeler
|
||||
|
||||
**Øvingskrav**
|
||||
* Kunne bruke arv til å modellerere enkle(re) objektstrukturer- og relasjoner i Java
|
||||
* Kunne la flere subklasser bruke funksjonalitet definert i samme superklasse
|
||||
* Kunne la en subklasse redefinere metoder definert i en superklasse
|
||||
* Kunne samle felles oppførsel til to eller flere subklasser i en felles abstrakt klasse
|
||||
|
||||
## Dette må du gjøre
|
||||
Oppgavene skal lagres i `ovinger/src/main/java/inheritance`.
|
||||
|
||||
I begge delene er antageligvis vanskelighetsgraden stigende. Alle er høyst eksamensrelevante og det anbefales følgelig å ta en titt på samtlige.
|
||||
|
||||
### Del 1: Arv
|
||||
Velg og gjennomfør *minst én* av oppgavene om arv:
|
||||
|
||||
* [CardContainerImpl](./CardContainerImpl.md)
|
||||
* [Train](./Train.md)
|
||||
* [SavingsAccount](./SavingsAccount.md)
|
||||
|
||||
### Del 2: Abstrakte klasser og arv
|
||||
Velg og gjennomfør *minst én* av oppgavene om abstrakte klasser og arv:
|
||||
|
||||
* [AbstractAccount](./AbstractAccount.md)
|
||||
* [ObservableList](./ObservableList.md)
|
||||
|
||||
|
||||
### Hjelp / mistanke om bugs
|
||||
|
||||
Ved spørsmål eller behov for hjelp konsulter studassen din i saltiden hans / hennes. Du kan også oppsøke andre studasser på sal eller legge ut et innlegg på [Piazza](https://piazza.com/).
|
||||
|
||||
### Godkjenning
|
||||
|
||||
Last opp kildekode på Blackboard innen den angitte innleveringsfristen. Innlevert kode skal demonstreres for en læringsassistent innen én uke etter innleveringsfrist. Se for øvrig Blackboard-sidene for informasjon rundt organisering av øvingsopplegget og det tilhørende øvingsreglementet.
|
||||
117
oppgavetekster/oving7/SavingsAccount.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# Arv - SavingsAccount-oppgave
|
||||
Denne oppgaven handler om å lage en felles superklasse `SavingsAccount` for
|
||||
`BSU`- og `ForeldreSpar`-klassene. `SavingsAccount` skal dessuten implementere
|
||||
`Account`-grensesnittet.
|
||||
|
||||
Denne oppgaven bygger videre på `Account`-oppgavene under
|
||||
[Innkapsling](../oving2/Account.md) og [Tilstand og oppførsel](../oving1/Account.md).
|
||||
|
||||
### Del 1 - SavingsAccount implements Account
|
||||
En bank består av mange ulike type kontoer: sparekontoer, brukskontoer,
|
||||
depositumskontoer, støttekontoer etc. Felles for alle kontoer er
|
||||
`Account`-grensesnittet, som er definert under:
|
||||
|
||||
```java
|
||||
package inheritance;
|
||||
|
||||
public interface Account {
|
||||
public void deposit(double amount);
|
||||
public void withdraw(double amount);
|
||||
public double getBalance();
|
||||
}
|
||||
```
|
||||
|
||||
Vi skal i denne oppgaven fokusere på sparekontoer og du skal nå lage en
|
||||
`SavingsAccount`-superklasse, som implementerer `Account`-grensesnittet.
|
||||
Funksjonaliteten som hver av metodene definert i grensesnittet over skal
|
||||
støtte er:
|
||||
|
||||
* `void deposit(double)` - øker kontobalansen med innskutt beløp. Merk at det
|
||||
innskutte beløpet må være positivt. Ved ulovlig innskudd skal en
|
||||
`IllegalArgumentException` utløses.
|
||||
* `void withdraw(double)` - minsker kontobalansen med beløpet som blir tatt ut.
|
||||
Merk at uttaksbeløpet må være positivt, ellers skal et unntak av typen
|
||||
`IllegalArgumentException` utløses. Dersom det ikke er dekning på kontoen
|
||||
(en `SavingsAccount` kan ikke ha negativ balanse) skal et unntak av typen
|
||||
`IllegalStateException` utløses.
|
||||
* `double getbalance()` - returnerer kontobalansen.
|
||||
|
||||
I tillegg til å støtte `Account`-grensesnittet over, som er felles for alle
|
||||
kontoer, skal sparekontoer ha en rentefot og en metode som forrenter kontoen.
|
||||
Denne kalles av bankene for hver sparekonto på slutten av året slik at alle
|
||||
dets kunder opptjener renter (ikke tenk på at banker egentlig holder styr på
|
||||
hvor stor balansen har vært gjennom hele året eller forrenter kontoen
|
||||
kontinuerlig - her skal vi bare anta at innestående kontobalanse ved årsslutt
|
||||
forrentes i sin helhet) - derfor heter metoden `endYearUpdate()`. I tillegg
|
||||
skal `SavingsAccount`-klassen ha en konstruktør som tvinger alle objekter
|
||||
av denne typen til å bli instansiert med en rentefot. Dette er oppsummert her:
|
||||
|
||||
* `SavingsAccount(double)` - konstruktør som tar inn rentefoten på kontoen
|
||||
(et desimaltall, f.eks. 0.05 tilsvarer en rente på 5 %). Åpningsbalansen
|
||||
skal være 0.
|
||||
* `void endYearUpdate()` - forrenter kontobalansen basert på rentefoten.
|
||||
Vi tenker oss at denne kalles av kode utenfor denne klassen, f.eks. resten
|
||||
av et tenkt banksystem ved årsoppgjør, som et signal på at nå er et nytt år
|
||||
over.
|
||||
|
||||
Vær oppmerksom på at du i Del 2 og 3 skal lage *subklasser* av `SavingsAccount`
|
||||
og at du ved å bruke rett innkapsling (hint: `protected`-modifikatoren) kan la
|
||||
*subklassene* nyttiggjøre seg *superklassen* i størst mulig grad.
|
||||
|
||||
Testkode for oppgavene finner du her: [inheritance/SavingsAccountTest.java](../../src/test/java/inheritance/SavingsAccountTest.java).
|
||||
|
||||
### Del 2 - BSU extends SavingsAccount
|
||||
I tillegg til generelle sparekontoer finnes det en spesiell type sparekonto
|
||||
som heter BSU. Du skal nå lage en `BSU`-klasse som arver fra
|
||||
`SavingsAccount`-superklassen. Her er målet at du skal gjenbruke mest mulig
|
||||
av *superklassen* og samtidig støtte BSU-spesifikk oppførsel. En BSU-konto er,
|
||||
i tillegg til å være en sparekonto, spesiell i den forstand at det kun er
|
||||
lovlig å sette inn inntil et forhåndsbestemt beløp per år
|
||||
(den gamle regjeringen fastslo at BSU-kontoer i 2014 skulle ha en
|
||||
innskuddsgrense på kr 25 000, men din kode skal ha støtte for å ha en vilkårlig
|
||||
grense) og at det kun er lovlig å ta ut av det beløpet som er satt inn siste
|
||||
år. M.a.o. vil en ved årsskifte få mulighet til å sette inn nye innskudd
|
||||
innenfor innskuddsgrensen, men en har ikke lenger mulighet til å ta ut hele
|
||||
balansen (innskudd fra tidligere år låses). Dessuten gir en vanlig BSU-konto
|
||||
20% skattefradrag for årets innskudd.
|
||||
|
||||
Du må selv avgjøre hvilke felt som må legges til for å støtte den beskrevne
|
||||
oppførsel. I tillegg stilles følgende krav til klassen:
|
||||
|
||||
* `BSU(double, double)` - konstruktør som tar inn rentefoten på kontoen og et
|
||||
desimaltall som angir hvor mye det er tillatt å sette inn på kontoen per år.
|
||||
* `double getTaxDeduction()` - returnerer skattefradrag for inneværende år.
|
||||
Dette vil være 20% av innskutt(e) beløp siste år.
|
||||
|
||||
Testkode for oppgavene finner du her: [inheritance/BSUTest.java](../../src/test/java/inheritance/BSUTest.java).
|
||||
|
||||
### Del 3 - ForeldreSpar extends SavingsAccount
|
||||
En annen spesiell type sparekonto, her kalt ForeldreSpar, har et begrenset
|
||||
antall lovlige uttak per år (ofte i bytte mot en høyere rente). Du skal nå
|
||||
lage en slik `ForeldreSpar`-klasse som arver fra `SavingsAccount`-superklassen.
|
||||
Her er igjen målet at du skal gjenbruke mest mulig av *superklassen* og
|
||||
samtidig støtte ForeldreSpar-spesifikk oppførsel. Denne klassen skal sikre at
|
||||
kun det lovlige antallet uttak gjøres i løpet av et år.
|
||||
|
||||
Du må selv avgjøre hvilke felt som må legges til før å støtte den beskrevne
|
||||
oppførsel. I tillegg stilles følgende krav til klassen:
|
||||
|
||||
* `ForeldreSpar(double, int)` - konstruktør som tar inn rentefoten på kontoen
|
||||
og et heltall som angir antall lovlige uttak per år.
|
||||
* `int getRemainingWithdrawals()` - returnerer antall gjenstående uttak fra
|
||||
sparekontoen.
|
||||
|
||||
Testkode for oppgavene finner du her: [inheritance/ForeldreSparTest.java](../../src/test/java/inheritance/ForeldreSparTest.java).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
72
oppgavetekster/oving7/Train.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# Arv - Train-oppgave
|
||||
|
||||
I denne oppgaven skal vi modellere to typer togvogner og bruke dem i et tog. Vi vil bruke
|
||||
arv og samle det som er felles for togvognene i en *superklasse*.
|
||||
|
||||
### Del 1 - TrainCar
|
||||
<img src="images/Train_del1.png" width="170">
|
||||
|
||||
I denne delen skal du lage en klasse kalt `TrainCar` for en enkel og generell
|
||||
togvogn, med følgende funksjonalitet (se også diagrammet over):
|
||||
|
||||
* `TrainCar(int)` - en konstruktør som tar inn hvor mye en tom vogn veier.
|
||||
* `int getTotalWeight` - returnerer vognas totale vekt. Merk at denne også skal
|
||||
kunne kalles på *subklasser* og fortsatt returnere totalvekta til vogna
|
||||
(stikkord: *redefinering*).
|
||||
* `setDeadWeight(int)` - setter hvor mye en tom vogn veier. Altså vekten til
|
||||
kun vognen, uten passasjerer eller last.
|
||||
* `int getDeadWeight()` - returnerer hvor mye en tom vogn veier. Altså vekten til
|
||||
kun vognen, uten passasjerer eller last.
|
||||
|
||||
Testkode for oppgaven finner du her: [inheritance/TrainCarTest.java](../../src/test/java/inheritance/TrainCarTest.java).
|
||||
|
||||
### Del 2 - CargoCar og PassengerCar
|
||||
<img src="images/Train_del2.png" width="350">
|
||||
|
||||
I denne delen skal du lage to forskjellige typer togvogner som er spesialiserte
|
||||
for sitt bruk. Begge skal arve fra `TrainCar`.
|
||||
##### CargoCar extends TrainCar:
|
||||
Denne klassen skal gjenspeile en lastevogn som frakter diverse ting og tang.
|
||||
Følgende funksjonalitet trengs (se også diagrammet over):
|
||||
|
||||
* `CargoCar(int, int)` - her tas inn hvor mye en tom vogn veier (som i `TrainCar`),
|
||||
og hvor mye vogna sin last veier.
|
||||
* `int getCargoWeight()` - returnerer hvor mye lasten veier.
|
||||
* `setCargoWeight(int)` - setter en ny verdi for vekten til lasten.
|
||||
|
||||
##### PassengerCar extends TrainCar:
|
||||
Denne klassen gjenspeiler en passasjervogn. Legg til følgende metoder
|
||||
(se også diagrammet over):
|
||||
|
||||
* `PassengerCar(int, int)` - her tas inn hvor mye en tom vogn veier
|
||||
(som i `TrainCar`), og hvor mange passasjerer det er i vogna.
|
||||
* `int getPassengerCount()` - returner antall passasjerer.
|
||||
* `setPassengerCount(int)` - setter en ny verdi for antall passasjerer.
|
||||
|
||||
For å beregne totalvekta, så kan du anta at en gjennomsnittspassasjer veier 80 kg.
|
||||
|
||||
Testkode for oppgavene finner du her: [inheritance/PassengerCarTest.java](../../src/test/java/inheritance/PassengerCarTest.java) og [inheritance/CargoCarTest.java](../../src/test/java/inheritance/CargoCarTest.java).
|
||||
|
||||
|
||||
### Del 3 - Train
|
||||
<img src="images/Train_del3.png" width="450">
|
||||
|
||||
Klassen `Train` skal forestille et tog bestående av et sett vogner.
|
||||
Klassen skal ha følgende metoder (se også diagrammet over):
|
||||
|
||||
* `addTrainCar(TrainCar)` - denne metoden skal ta inn en togvogn og knytte den
|
||||
til dette lokomotivet.
|
||||
* `boolean contains(TrainCar)` - Sjekker om lokomotivet har `TrainCar`-argument
|
||||
knyttet til seg.
|
||||
* `int getTotalWeight()` - returner alle vognene sin totale vekt. Vi tar ikke
|
||||
høyde for lokomotivet sin eventuelle vekt.
|
||||
* `int getPassengerCount()` - tilsvarende `PassengerCar` sin metode, men
|
||||
returnerer antallet for alle vognene.
|
||||
* `int getCargoWeight()` - tilsvarende `CargoCar` sin metode, men returnerer
|
||||
lastevekten for alle vognene.
|
||||
* `String toString()` - `toString`-metoden skal sette sammen en *String* med
|
||||
oversikt over alle vognene som er knyttet til den. For hver vogn skal vogntype
|
||||
og totalvekt være med. Passasjervogner skal i tillegg ha med antall passasjerer
|
||||
og lastevogner skal ha med hvor mye lasten veier.
|
||||
|
||||
Testkode for oppgaven finner du her: [inheritance/TrainTest.java](../../src/test/java/inheritance/TrainTest.java).
|
||||
BIN
oppgavetekster/oving7/images/ObservableList_del1.png
Normal file
|
After Width: | Height: | Size: 81 KiB |
BIN
oppgavetekster/oving7/images/ObservableList_del2.png
Normal file
|
After Width: | Height: | Size: 116 KiB |
BIN
oppgavetekster/oving7/images/ObservableList_del3.png
Normal file
|
After Width: | Height: | Size: 118 KiB |
BIN
oppgavetekster/oving7/images/Train_del1.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
oppgavetekster/oving7/images/Train_del2.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
oppgavetekster/oving7/images/Train_del3.png
Normal file
|
After Width: | Height: | Size: 103 KiB |