Java Arena
Step 7 of 7

Interfaces, and a whole program

An interface's box

An interface (module 35) gets a box like a class, with «interface» above its name. It has no instance variables and no constructor, so below its name, its box lists only the methods.

The recycling center's weighing station weighs anything that can say what it weighs, so it has an interface Weighable. A crate of bottles and a bale of paper both implement it:

The diagram as text
  • Weighable, an interface
    • public method weight(): int
  • Crate, a class that implements Weighable
    • private field bottles: int
    • public constructor Crate(bottles: int)
    • public method weight(): int
  • Bale, a class that implements Weighable
    • private field kilos: int
    • public constructor Bale(kilos: int)
    • public method weight(): int
  • The interface's methods are public, +. The interface only lists them, so a line for each is all there is to show.
  • A class that implements the interface is joined to it by a dashed line with a hollow triangle at the interface: the triangle of extends, dashed for implements.
  • Each class's box lists the interface's methods again, since each class writes them.
  • A class that implements several interfaces has a dashed line to each of them.
Main.java
import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        ArrayList<Weighable> station = new ArrayList<>();
        station.add(new Crate(24));
        station.add(new Bale(250));
        int total = 0;
        for (Weighable item : station) {
            total += item.weight();
        }
        System.out.println(total + " kg");
    }
}
Weighable.java
public interface Weighable {
    int weight();
}
Crate.java
public class Crate implements Weighable {
    private int bottles;

    public Crate(int bottles) {
        this.bottles = bottles;
    }

    @Override
    public int weight() {
        return 2 + this.bottles / 2;
    }
}
Bale.java
public class Bale implements Weighable {
    private int kilos;

    public Bale(int kilos) {
        this.kilos = kilos;
    }

    @Override
    public int weight() {
        return this.kilos;
    }
}
Output
264 kg

A whole program

A diagram of a whole program uses everything at once. Here's the weighing station with a Scale that remembers what it has weighed, and old tires, from step 6, that can be weighed as well:

The diagram as text
  • Weighable, an interface
    • public method weight(): int
  • DropOff, an abstract class
    • private field kilos: int
    • public constructor DropOff(kilos: int)
    • public abstract method fee(): int
    • more members, not shown
  • Tires, a class that extends DropOff and implements Weighable
    • private field count: int
    • public constructor Tires(kilos: int, count: int)
    • public method fee(): int
    • public method weight(): int
  • Crate, a class that implements Weighable
    • private field bottles: int
    • public constructor Crate(bottles: int)
    • public method weight(): int
  • Scale, a class
    • public constructor Scale()
    • public method weigh(item: Weighable): void
    • public method total(): int

Connections:

  • Each Scale has any number of Weighable objects (weighed).

To read a diagram like this, go through it in layers:

  1. The boxes. What each one is: a class, an abstract class («abstract») or an interface («interface»).
  2. The triangles. Each solid one is an extends, each dashed one an implements. Tires does both: it extends DropOff and implements Weighable.
  3. The arrows. Each is a field, and a star makes it a list. The Scale keeps a list of Weighables: it can weigh crates and tires alike, and any class that implements Weighable later.
  4. The members, box by box. A line ... stands for members that the diagram leaves out, as in DropOff's box: step 6 showed the rest.

To write the program, start with what needs no other class of the diagram: here the interface and DropOff. Then write the classes that extend or implement them, Tires and Crate, and last the classes whose arrows point at the others, the Scale. Each file then compiles as soon as it's written, since everything it names is already there.

Your task

Challenge 1 of 3

The ward's cleaning staff clean anything that's Cleanable. Cleanable.java is ready. Write the class Wheelchair in Wheelchair.java, as the diagram shows:

The diagram as text
  • Cleanable, an interface
    • public method clean(): void
    • public method isClean(): boolean
  • Wheelchair, a class that implements Cleanable
    • private field number: int
    • private field uses: int
    • public constructor Wheelchair(number: int)
    • public method use(): void
    • public method clean(): void
    • public method isClean(): boolean
    • public method toString(): String
  • A new wheelchair is clean: it has had no uses since it was last cleaned.
  • use counts one use, and clean sets the count back to 0.
  • isClean says whether the wheelchair has had no uses since it was last cleaned.
  • toString returns Wheelchair 7: 2 uses since cleaning.

The check runs:

Wheelchair chair = new Wheelchair(7);
chair.use();
chair.use();
System.out.println(chair + " " + chair.isClean());
Cleanable job = chair;
job.clean();
System.out.println(chair + " " + chair.isClean());

and expects:

Wheelchair 7: 2 uses since cleaning false
Wheelchair 7: 0 uses since cleaning true

Challenge 2

Here are the tires of step 6 in the weighing station's diagram. Fill in the three blanks, words from class headers, so that the code matches the diagram.

The diagram as text
  • Weighable, an interface
    • public method weight(): int
  • DropOff, an abstract class
    • private field kilos: int
    • public constructor DropOff(kilos: int)
    • public method getKilos(): int
    • public abstract method fee(): int
  • Tires, a class that extends DropOff and implements Weighable
    • private field count: int
    • public constructor Tires(kilos: int, count: int)
    • public method fee(): int
    • public method weight(): int

Challenge 3

To close the module, a whole program from one diagram. A board-game café bills each visit for table time and drinks. Write the four parts of this diagram, each in its own file:

The diagram as text
  • Billable, an interface
    • public method price(): int
  • TableTime, a class that implements Billable
    • private field hours: int
    • private field players: int
    • public constructor TableTime(hours: int, players: int)
    • public method price(): int
  • Drink, a class that implements Billable
    • private field name: String
    • private field large: boolean
    • public constructor Drink(name: String, large: boolean)
    • public method price(): int
  • Visit, a class
    • private field guest: String
    • public constructor Visit(guest: String)
    • public method add(item: Billable): void
    • public method total(): int
    • public method toString(): String

Connections:

  • Each Visit has any number of Billable objects (items).
  • Table time costs 3 dollars per player per hour.
  • A drink costs 4 dollars, or 6 if it's large.
  • A new visit has nothing on its bill. add puts an item on it, and total returns the prices of the visit's items added up.
  • A visit's toString returns Visit of Ana: 3 items, 34 dollars, with the visit's own guest, number of items and total.

The check runs:

Visit visit = new Visit("Ana");
visit.add(new TableTime(2, 4));
visit.add(new Drink("cocoa", true));
visit.add(new Drink("tea", false));
System.out.println(visit);
System.out.println(new TableTime(1, 3).price());

and expects:

Visit of Ana: 3 items, 34 dollars
9