Java Arena
Step 4 of 7

Arrows between classes

So far each box stood alone. In a program, objects hold references to other objects, and a class diagram shows that with lines between the boxes.

A field that refers to another class

A theater stages plays, and each play gets many performances. The program has a class for each, and a Performance holds a reference to its Play:

public class Performance {
    private Play play;
    private String date;
    private int seatsSold;

    // the constructor and methods
}

In a diagram, a field whose type is another class of the diagram isn't written in the box. It's drawn as an arrow, from the box of the class that has the field to the box of the class it refers to:

The diagram as text
  • Play, a class
    • private field title: String
    • private field minutes: int
    • public constructor Play(title: String, minutes: int)
    • public method getTitle(): String
    • public method getMinutes(): int
  • Performance, a class
    • private field date: String
    • private field seatsSold: int
    • public constructor Performance(play: Play, date: String)
    • public method sell(seats: int): void
    • public method toString(): String

Connections:

  • Each Performance has one Play object (play).
  • The arrow goes from Performance to Play: a Performance knows its Play. It has a field of type Play, so its methods can call the play's methods.
  • A Play doesn't know its performances. It has no field for them, and the arrow doesn't point back: given a Play object, there's no way to reach its performances.
  • The 1 at the arrowhead is the multiplicity: each Performance has exactly one Play. An arrow without a number at its head means one, too.
  • The name by the arrow, play, is the field's name. It's optional, and handy when a class has two fields of the same type.
  • play: Play in the constructor is a parameter, so it stays in the box. Only the field turns into an arrow.
  • date: String stays in the box, though String is a class too. Arrows connect the program's own classes, the ones drawn in the diagram. Java's classes, such as String and ArrayList, are written as types.

Here's the code:

Main.java
public class Main {
    public static void main(String[] args) {
        Play hamlet = new Play("Hamlet", 190);
        Performance friday = new Performance(hamlet, "May 9");
        Performance saturday = new Performance(hamlet, "May 10");
        friday.sell(120);
        saturday.sell(95);
        friday.sell(30);
        System.out.println(friday);
        System.out.println(saturday);
    }
}
Play.java
public class Play {
    private String title;
    private int minutes;

    public Play(String title, int minutes) {
        this.title = title;
        this.minutes = minutes;
    }

    public String getTitle() {
        return this.title;
    }

    public int getMinutes() {
        return this.minutes;
    }
}
Performance.java
public class Performance {
    private Play play;
    private String date;
    private int seatsSold;

    public Performance(Play play, String date) {
        this.play = play;
        this.date = date;
        this.seatsSold = 0;
    }

    public void sell(int seats) {
        this.seatsSold += seats;
    }

    @Override
    public String toString() {
        return this.play.getTitle() + " (" + this.play.getMinutes() + " min), " + this.date + ": " + this.seatsSold + " seats sold";
    }
}
Output
Hamlet (190 min), May 9: 150 seats sold
Hamlet (190 min), May 10: 95 seats sold

Both performances refer to the same Play object. "Each Performance has one Play" says how many plays a performance has, not that their plays are different objects: many performances can share one play, as friday and saturday do.

One, or none

A reference can also be null. A multiplicity of 0..1 at the arrowhead means at most one: zero or one. Say a critic may review a performance, or not:

The diagram as text
  • Performance, a class
    • private field date: String
    • private field seatsSold: int
  • Review, a class
    • private field critic: String
    • private field stars: int

Connections:

  • Each Performance has at most one Review object (review).

Performance's field review is null until a review comes in, so code that uses it has to check for null first. With 1, the code can count on the field always referring to an object.

Your task

Challenge 1 of 3

The theater's costume department sews each costume for one actor, who wears it as one character. Actor.java is ready. Write the class Costume in Costume.java, as the diagram shows:

The diagram as text
  • Actor, a class
    • private field name: String
    • private field height: int
    • public constructor Actor(name: String, height: int)
    • public method getName(): String
    • public method getHeight(): int
  • Costume, a class
    • private field character: String
    • public constructor Costume(character: String, actor: Actor)
    • public method getActor(): Actor
    • public method toString(): String

Connections:

  • Each Costume has one Actor object (actor).

getActor returns the costume's actor, and toString returns Puck, for Noor Haddad (172 cm), with the costume's own character and its actor's name and height. The check runs:

Actor noor = new Actor("Noor Haddad", 172);
Costume puck = new Costume("Puck", noor);
Costume moth = new Costume("Moth", noor);
System.out.println(puck);
System.out.println(moth.getActor().getName());

and expects:

Puck, for Noor Haddad (172 cm)
Noor Haddad

Challenge 2

The theater's director cuts some scenes, and the play gets shorter. Here are the Play and Performance of the lesson, with one more method in Play:

The diagram as text
  • Play, a class
    • private field title: String
    • private field minutes: int
    • public constructor Play(title: String, minutes: int)
    • public method getTitle(): String
    • public method getMinutes(): int
    • public method cut(minutes: int): void
  • Performance, a class
    • private field date: String
    • private field seatsSold: int
    • public constructor Performance(play: Play, date: String)
    • public method sell(seats: int): void
    • public method toString(): String

Connections:

  • Each Performance has one Play object (play).

What does this program print?

Challenge 3

The ward's program has grown: a bed now holds a Patient object instead of a name, and a free bed holds none.

The diagram as text
  • Patient, a class
    • private field name: String
    • private field room: int
    • private field temperature: double
    • public constructor Patient(name: String, room: int, temperature: double)
    • public method getName(): String
    • public method toString(): String
  • Bed, a class
    • private field number: int
    • public constructor Bed(number: int)
    • public method getPatient(): Patient
    • public method assign(patient: Patient): boolean
    • public method release(): void
    • public method toString(): String

Connections:

  • Each Bed has at most one Patient object (patient).

Patient.java is ready. Write the class Bed in Bed.java:

  • A new bed is free: its patient is null.
  • assign puts the patient in the bed and returns true, but only if the bed is free. A bed that has a patient keeps them, and assign returns false.
  • release makes the bed free, and getPatient returns the bed's patient, or null for a free bed.
  • toString returns Bed 3: free, or Bed 3: Ines Moreau with the patient's name.

The check runs:

Bed bed = new Bed(3);
Patient ines = new Patient("Ines Moreau", 12, 38.4);
Patient oskar = new Patient("Oskar Lund", 12, 36.9);
System.out.println(bed);
System.out.println(bed.assign(ines) + " " + bed.assign(oskar));
System.out.println(bed);
bed.release();
System.out.println(bed.getPatient() == null);

and expects:

Bed 3: free
true false
Bed 3: Ines Moreau
true