5.5. Relationer mellem objekter

Indtil nu har alle vore objekter haft simple typer som variabler. Nu vil vi se på objekter der har andre objekter som variabler (dvs. de har referencer til andre objekter).

5.5.1. En Raflebæger-klasse

Når man laver et større program, bliver det ofte nødvendigt at uddelegere nogle af opgaverne fra hovedprogrammet til andre dele af programmet. I vores tilfælde kunne vi godt lave et lille terningspil direkte fra main(), men hvis vi skulle lave f.eks. et yatzy- eller matadorspil, ville det blive besværligt at skulle holde rede på hver enkelt terning (og alle de andre objekter) på den måde. Hver gang en spiller kaster med terningerne, skal man først kaste hver enkelt terning, hvorefter man skal udregne summen (eller i Yatzy undersøge antallet af par, tre ens osv.).

En løsning er at skabe andre, mere overordnede objekter, som tager sig af detaljerne.

I vores tilfælde kan man definere en Raflebæger-klasse, der 'har' terningerne, og som er bekvem at bruge fra hovedprogrammet. Med 'har' menes, at referencerne til Terning-objekterne kendes af raflebægeret, men ikke nødvendigvis af hovedprogrammet.

Raflebægeret har metoderne ryst(), der kaster alle terningerne, sum(), der udregner summen af terningernes værdier og antalDerViser(), der fortæller hvor mange terninger, der har en given værdi (f.eks. hvor mange terninger der viser 6 øjne).

import java.util.*;

public class Raflebaeger
{
  public Vector terninger;  // Raflebaeger har en vektor af terninger

  public Raflebaeger(int antalTerninger)
  {
    terninger = new Vector();
    for (int i=0;i<antalTerninger;i++)
    {
      Terning t;
      t = new Terning();
      tilføj(t);
    }
  }

  public void tilføj(Terning t)       // Læg en terning i bægeret
  {
    terninger.addElement(t);
  }

  public void ryst()                  // Kast alle terningerne
  {
    for (int i=0;i<terninger.size();i++) 
    {
      Terning t;
      t = (Terning) terninger.elementAt(i);
      t.kast();
    }
  }

  public int sum()                    // Summen af alle terningers værdier
  {
    int resultat;
    resultat=0;
    for (int i=0;i<terninger.size();i++) 
    {
      Terning t;
      t = (Terning) terninger.elementAt(i);
      resultat = resultat + t.værdi;
    }
    return resultat;
  }
  
  public int antalDerViser(int værdi) // Antal terninger med en bestemt værdi
  {
    int resultat;
    resultat = 0;
    for (int i=0;i<terninger.size();i++) 
    {
      Terning t;
      t = (Terning) terninger.elementAt(i);
      if (t.værdi==værdi) 
      {
        resultat = resultat + 1;
      }
    }
    return resultat;
  }

  public String toString ()           // Beskriv bægerets indhold
  {// (vektorens toString() kalder toString() på hver terning)
    return terninger.toString();
  }
}

Herunder er et lille program der spiller med tre terninger indtil man får netop to seksere:

public class ToSeksere
{
  public static void main(String[] args)
  {  
    Raflebaeger bæger;
    boolean toSeksere;
    int antalForsøg;

    bæger = new Raflebaeger(3);   // opret et bæger med 3 terninger
    toseksere=false;
    antalForsøg = 0;
    while (toseksere==false)
    {
      bæger.ryst();              // kast alle terningerne
      System.out.print("Bæger: " + bæger + " sum: " + bæger.sum());
      System.out.println(" Antal 6'ere: "+bæger.antalDerViser(6)
                       + " antal 5'ere: "+bæger.antalDerViser(5));
      if (bæger.antalDerViser(6) == 2)
      {
        toSeksere = true;
      }
      antalForsøg++;
    }
    System.out.println("Du fik to seksere efter "+ antalForsøg+" forsøg.");
  }
}
Bæger: [4, 4, 4] sum: 12 Antal 6'ere: 0 antal 5'ere: 0
Bæger: [5, 5, 6] sum: 16 Antal 6'ere: 1 antal 5'ere: 2
Bæger: [2, 5, 6] sum: 13 Antal 6'ere: 1 antal 5'ere: 1
Bæger: [4, 2, 4] sum: 10 Antal 6'ere: 0 antal 5'ere: 0
Bæger: [6, 4, 1] sum: 11 Antal 6'ere: 1 antal 5'ere: 0
Bæger: [6, 6, 4] sum: 16 Antal 6'ere: 2 antal 5'ere: 0
Du fik to seksere efter 6 forsøg.

Linjen:

    bæger = new Raflebaeger(3);

opretter et raflebæger med tre terninger i.

5.5.2. Opgaver

  1. Skriv et program, der vha. et Raflebaeger rafler med fire terninger, indtil der slås tre eller fire 6'ere. Udskriv antal øjne for hver terning.

  2. Skriv et program, der vha. et Raflebaeger rafler med 12 terninger og udskriver terningernes værdier, summen af værdierne og hvor mange 6'ere der kom.

  3. Skriv et simpelt Yatzy-spil med fem terninger. Man kaster én gang og ser om man har et par, to par, tre ens, hus (et par og tre ens, f.eks. 25225), fire ens eller fem ens.

Udvid Raflebaeger så man kan spørge, om der er fire ens, ved at kalde en fireEns()-metode:

  public boolean fireEns() 
  { 
    ... 
  }

Lav tilsvarende de andre metoder.

Ret toString()-metoden, så den fortæller, om der var fem ens, hus eller lignende.

Lav et program (en klasse med en main()-metode), der rafler et Raflebaeger et par gange og skriver dets indhold ud. Her er et eksempel på, hvordan uddata kunne se ud:

1 4 4 3 4  : Tre ens
4 2 1 6 6  : Et par
2 6 2 2 6  : Hus
5 2 3 6 4  : Ingenting
2 3 4 5 4  : Et par
6 5 2 6 2  : To par
6 6 2 2 6  : Hus
...