You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 14 Next »

Denne oppgaven handler om et grensnitt (interface) for rutenett som holder strenger (StringGrid), hvordan slike implementeres og hvordan en kan iterere gjennom et slikt rutenett ved hjelp av en Iterator.

I denne oppgaven tar vi utgangspunkt i et StringGrid-grensesnitt som definerer metodene til et rutenett som holder strenger. Et rutenett er firkantet og består av et antall rader og kolonner. Det skal være mulig å spørre rutenettet hvilken streng som er på angitt rad og kolonne i tillegg til å endre strengen på angitt rad og kolonne. Denne oppførselen er oppsummert i det definerte StringGrid-grensesnittet under:

package interfaces;

public interface StringGrid {

	public int getRowCount();
	public int getColumnCount();

	public String getElement(int row, int column);
	public void setElement(int row, int column, String element);
}

Alle klasser som implementerer StringGrid-grensesnittet må støtte de fire definerte metodene.

Del 1 - StringGrid-grensesnitt og implementerende StringGridImpl-klasse

Lag en StringGridImpl-klasse som implementerer StringGrid-grensesnittet definert over. Du står fritt til å velge hvordan metodene definert av grensesnittet skal implementeres så lenge den tilfredsstiller den definerte oppførselen. To mulige løsninger for representasjon av rutenettet er en enkel ArrayList<String> eller en dobbel ArrayList<ArrayList<String>> der den ytre listen er radene og de indre kolonnene. Wikisiden om todimensjonale matriser kan være lurt å ta en titt på før du går i gang hvis du velger sistnevnte rutenettrepresentasjon. Dersom getElement(int, int)- eller setElement(int, int, String)-metodene kalles med ulovlige verdier for rad eller kolonne (i.e. de er utenfor rutenettet), skal en IllegalArgumentException kastes. 

Del 2 - StringGridIterator-klasse

Det er hensiktmessig å kunne iterere over et rutenett som implementerer grensesnittet StringGrid - f.eks. når en bygger en streng i en toString()-metode eller skal sjekke om et spill har blitt avsluttet / vunnet. For å kunne gjøre dette skal vi nå lage en iteratorklasse for StringGrid-grensesnitt, kalt StringGridIterator. Denne klassen må implementere grensesnittet Iterator<String>, ha et felt for et objekt av typen StringGrid og støtte metodene definert av grensesnittet ved å iterere gjennom dette objektet. For å kunne velge om en vil iterere over rutenettet bortover først (rowMajor=true) eller nedover først (rowMajor=false) må du også ha et felt boolean rowMajor som holder styr på hvordan rutenettet skal itereres. StringGridIterator-klassen må altså støtte følgende konstruktør / metoder:

  • StringGridIterator(StringGrid, boolean) - konstruktør som tar inn StringGrid-objektet som StringGridIterator-klassen skal iterere over i tillegg til en boolsk verdi som angir om iterasjonen skal være bortover først (rowMajor=true) eller nedover først (rowMajor=false).
  • boolean hasNext() - returnerer true så lenge det er flere strenger igjen i StringGrid-objektet som ikke enda er blitt iterert over (i.e. sjekk om du har kommet til siste rute i rutenettet).

  • String next() - returnerer den neste strengen i rutenettet. Hvilken streng som er den neste til å bli returnert avhenger av hvordan rutenettet skal itereres (i.e. om rowMajor=true eller rowMajor=false).

  • void remove() - denne metoden skal bare kaste et unntak av typen UnsupportedOperationException siden det ikke skal være mulig å fjerne strenger fra rutenettet.

Iterator-objektet som returneres av iterator()-metoden i StringGridImpl-klassen itererer over StringGridImpl-klassen på én bestemt måte.

Del 3 - StringGridIterable-grensesnitt og implementerende StringGridIterableImpl-klasse

Som en siste utvidelse, ønsker vi nå å gjøre StringGrid-grensesnittet itererbart. Ved å legge til extends Iterable<String> bak grensesnittnavnet StringGrid tvinger vi alle klasser som implementerer gresesnittet til også å være itererbare. Da skal det være mulig å iterere over implementerede klasse, f.eks. StringGridImpl-klassen du lagde i Del 1, ved å spørre Iterator-objektet om neste streng i rutenettet. Dette modifiserte grensesnittet (som arver fra Iterable<String>), kalt StringGridIterable, er vist i kodeblokken under:

package interfaces;

public interface StringGridIterable extends Iterable<String> {

	public int getRowCount();
	public int getColumnCount();

	public String getElement(int row, int column);
	public void setElement(int row, int column, String element);
}

Klasser som implementerer StringGridIterable-grensesnittet må nå støtte alle metodene som er definert i grensesnittet i tillegg til metoden:

 

public Iterator<String> iterator()

som returnerer et Iterator<String>-objekt som skal kunne spørres om neste streng i rutenettet for iterasjon. Du skal nå lage en siste klasse StringGridIterableImpl, hvor du kopierer koden fra StringGridImpl, men skal implementere grensesnittet StringGridIterable i stedet for StringGrid. Dette betyr i praksis at du bare trenger å legge til implementasjon av iterator()-metoden beskrevet over i StringGridIterableImpl-klassen. Her kan det være lurt å ta i bruk StringGridIterator-klassen du laget i Del 2 av denne oppgaven.


JExercise-testkode for del 1 og del 2 finner du her: interfaces/StringGridTest.java. Originalkoden (jextest) for testen finner du her: interfaces/StringGrid.jextest


JExercise lar deg sjekke din egen kode vha. forhåndslagde JUnit-tester og JExercise-panelet

Bruk av JExercise:

  1. Sørg for at jexercise-standalone.jar er lagt til i ditt prosjekts Build Path. Dette må gjøres hver gang du oppretter et nytt prosjekt, og det er derfor lurt å gjenbruke samme prosjekt til alle oppgaver.
  2. JExercise-tillegget må være installert. Installer tillegget fra følgende oppdateringsadresse: http://folk.ntnu.no/hal/dev/updatesite.
  3. Åpne JExercise-panelet via Window -> Show View -> Other, og navigere deg fram til JExercise i vinduet som kommer opp, velge det og klikke OK.
  4. Klikke og dra oppgavens testklasse, <oppgavenavn>Test.java fra pakkeoversikten og slippe den i JExercise panelet. 
  5. Testene kan så kjøres ved å dobbeltklikke på testen som ønskes kjørt.

Ved trøbbel, se først om du finner løsningen i Løsninger på trøbbel med JExercise.

Unknown macro: {html}

Twitre gjerne om oppgaven når du er ferdig: <a href="https://twitter.com/share" class="twitter-share-button" data-hashtags="jexercise">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>

  • No labels