Institutionen för datavetenskap Umeå Universitet

Lablektion 4

Biologen och grodynglen!

Lablektionens syfte är att i datorlabbet prova på att själv skriva kod. Uppgifterna är relativt korta och enkla och uppfyller lite av tanken att repetition hjälper inlärning. Hjälp finns att tillgå i labbet under lablektionstiden och andra tider så är det bara att skicka ett mail till Daniel, Johan eller Set.

Försök att lösa uppgifterna enskilt först men om du kör fast så fråga gärna. Denna gång kommer ni att skapa en klass per uppgift. Tillsammans kommer de att sitta ihop i ett större system där klasserna hänger ihop på olika sätt.

Här finns lösningsförslag som zip-fil.

Bakgrund

Denna övning går ut på att modellera ett system där en ung fältbiolog springer omkring och inventerar grodyngel i olika sorters vattenmassor. Vi kommer att ha en klass för fältbiologen, som kan inventera vattenmassor och berätta hur många grodyngel som hittats hittils. För att representera vattenmassornas minsta beståndsdel kommer vi ha en klass som representerar en vattendroppe och som möjligen kan innehålla ett grodyngel. Eftersom grodynglen inte fyller nån mer funktion än att räknas kommer vi nöja oss med att låta dem vara ett enkelt attribut i Vattendroppe. (De hade ju också kunnat få vara klasser)

Sedan kommer vi konstruera tre olika klasser som representerar vattensamlingar av olika storlek. Dessa kommer innehålla vattendroppar samlade i fält av olika storlekar (en-, två- och tredimensionella) och en metod som går igenom fältet och returnerar hur många grodyngel som finns samlade i vattenmassan. För att underlätta för vår stackars fältbiolog kommer dessa klasser ärva från en gemensam superklass. Men vi tar det steg för steg...

Repetitionsuppgift

Om du inte gjort övningarna på föregående lablektion, eller om du känner dig lite osäker på loopar och fält så gör den här uppgiften:
Skriv en metod higher som tar emot ett fält av heltal och en heltal n och
returnerar ett nytt fält som innehåller de tal i fältet som var större än n.
Exempel:
int tal[] = {5,11,2,1,7,9};
Nu borde higher(tal, 6) returnera fältet {11,7,9}
För enkelhetens skull kan ni låta det nya fältet vara lika stort som det gamla fältet när ni skapar det.

Uppgifter

Gemensam superklass

Skapa en abstrakt klass Vattenmassa som innehåller en abstrakt metod public int räknaGrodyngel(). Att klassen är abstrakt innebär att denna klass inte kan instansieras, utan den fungerar bara som en gemensam superklass för våra andra klasser som kommer att beskriva olika typer av vattenmassor. Att metoden är abstrakt innebär att varje klass som ärver från denna klass måste omdefinera denna metod. Kolla gärna i föreläsningsanteckningarna om ni är osäkra på hur man skriver abstrakta klasser.

Vattendroppe

Vi ska nu skapa en klass som beskriver den minsta möjliga beståndsdelen i alla vattenmassor, en vattendroppe. Skapa alltså en klass Vattendroppe, denna bör ha ett boolsk attribut som anger om det finns ett grodyngel i droppen. I konstruktorn ska slumpen få bestämma om någon grodyngel ska finnas. (Antingen med en fast sannolikhet, eller så kan ni ta in ett argument till konstuktorn) Eftersom man bör ha sina attribut privata så bör ni också skapa en metod public boolean harGrodyngel() som berättar om det finns ett grodyngel i droppen eller inte.

Ränna

Den första sortens vattensamling vi skapar är en ränna. Eftersom en ränna är en sorts vattenmassa så ska den ärva från Vattenmassa. Internt ska Ränna bestå av ett endimensionellt fält av klassen Vattendroppe. Låt alltså denna klass ha ett sådant som attribut. Klassens konstruktor behöver då loopa igenom detta fält och initiera det, fylla i det med Vattendroppe-objekt. Som argument bör konstruktorn ta åtminstone ett heltal som bestämmer hur långt fältet ska vara. Klassen ska också ha metoden public int räknaGrodyngel() som loopar igenom fältet och räknar hur många av vattendropparna som innehåller ett grodyngel.

Vattenpöl

Den andra vattensamlingen vi skapar är en vattenpöl, som också ärver från Vattenmassa. Internt ska Vattenpöl bestå av ett tvådimensionellt fält av klassen Vattendroppe. Den här klassens konstruktor behöver alltså loopa igenom ett tvådimensionellt fält på ungefär samma sätt som förra klassen gjorde. Ni kan lugnt börja med att kopiera över all kod eftersom klasserna kommer bli väldigt lika. (Kom ihåg att ändra alla namn ni behöver ändra) Istället för en längd ska denna konstruktor ta in en höjd och en bredd. Metoden public int räknaGrodyngel() kommer ju också att behöva loopa igenom ett tvådimensionellt fält.

Sjö

Den tredje sortens vattensamling vi skapar är en sjö. Där rännan var endimensionell och vattenpölen var tvådimensionell ska ju denna vara tredimensionell. På med en till loop och en till nivå i fälten alltså alltså. Lägg också till ett argument för djup till konstruktorn.

En stackars biolog

Nu ska vi alltså konstruera vår stackars fältbiolog som får springa omkring ute i regnet och räkna grodyngel när vi andra får sitta inne i värmen och programmera. Skapa alltså en klass Biolog. Vi kommer att göra det till en ganska enkel klass. Ett enda attribut som bestämmer hur många grodyngel som biologen har hittat hittils. Sedan behöver vi två metoder. En metod för att räkna grodyngel i en vattenmassa. Låt den metoden heta public void inventera(Vattenmassa vm) och helt enkelt summera grodynglen i den vattenmassan med summan hittils. Här ser vi tydligt att arvet tillåter oss att skriva en enkel metod som kan ta in vilken klass som helst som ärver från Vattenmassa och använda den för att räkna grodyngel. Låt biologen också ha en klass public int rapportera() som returnerar hur många grodyngel som har hittats totalt.

Nu är vi färdiga med vårt system, som till slut är ganska avancerat med flera olika sorters relationer mellan våra klasser, och ett snyggt utnyttjande av arv. Prova att skapa en biolog några objekt av olika typer av vattenmassor och räkna igenom dem... och glädjs över att ni slipper vara ute i regnet på riktigt och räkna grodyngel!

Denna lablektion är utvecklad av Daniel Lundmark och Johan Tordsson.


http://www.cs.umu.se/kurser/TDBA54/SU02/LLmaterial/LL4/index.html
Ansvarig för sidan: Johan Tordsson
Senast ändrad 2002-06-24