Java Arena
Step 6 of 7

Inheritance and abstract classes

A triangle points to the parent

Inheritance (module 34) has a line of its own in a class diagram. The recycling center's glass bins are sorted by color, so a GlassBin extends Bin with a color:

The diagram as text
  • Bin, a class
    • private field material: String
    • private field capacity: int
    • private field load: int
    • public constructor Bin(material: String, capacity: int)
    • public method add(kilos: int): boolean
    • public method toString(): String
  • GlassBin, a class that extends Bin
    • private field color: String
    • public constructor GlassBin(color: String, capacity: int)
    • public method toString(): String
  • The subclass's box is below its parent's, joined to it by a line with a hollow triangle at the parent's end. The triangle points to the class that is extended: GlassBin extends Bin.
  • The subclass's box shows only what GlassBin itself writes: its own field, its constructor, and the toString it overrides. It inherits add, but add is drawn once, in Bin's box.
  • Bin's private fields aren't repeated in GlassBin's box either. They're declared in Bin, even though every GlassBin object has them.
Main.java
public class Main {
    public static void main(String[] args) {
        GlassBin green = new GlassBin("green", 400);
        green.add(120);
        System.out.println(green);
    }
}
Bin.java
public class Bin {
    private String material;
    private int capacity;
    private int load;

    public Bin(String material, int capacity) {
        this.material = material;
        this.capacity = capacity;
        this.load = 0;
    }

    public boolean add(int kilos) {
        if (this.load + kilos > this.capacity) {
            return false;
        }
        this.load += kilos;
        return true;
    }

    @Override
    public String toString() {
        return this.material + ": " + this.load + "/" + this.capacity + " kg";
    }
}
GlassBin.java
public class GlassBin extends Bin {
    private String color;

    public GlassBin(String color, int capacity) {
        super("glass", capacity);
        this.color = color;
    }

    @Override
    public String toString() {
        return this.color + " " + super.toString();
    }
}
Output
green glass: 120/400 kg

When several classes extend one parent, the children sit side by side under it, and their lines meet at the parent's one triangle.

Abstract classes

An abstract class (module 34) is drawn like any other class, with two marks: «abstract» above its name, which is in italics, and its abstract methods in italics too.

People also bring the recycling center things that don't go in a bin, and pay a fee that depends on what they bring:

The diagram as text
  • DropOff, an abstract class
    • private field kilos: int
    • public constructor DropOff(kilos: int)
    • public method getKilos(): int
    • public abstract method fee(): int
    • public method toString(): String
  • Furniture, a class that extends DropOff
    • public constructor Furniture(kilos: int)
    • public method fee(): int
  • Electronics, a class that extends DropOff
    • private field screen: boolean
    • public constructor Electronics(kilos: int, screen: boolean)
    • public method fee(): int
  • DropOff's name is in italics under «abstract»: there are no objects of DropOff itself, only Furniture and Electronics objects.
  • fee() is in italics in DropOff's box: it's abstract there, a header without a body. Each subclass writes it, so it's in their boxes again, in plain letters.
  • A subclass can have no fields of its own, like Furniture, whose field part is empty.
Main.java
import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        ArrayList<DropOff> today = new ArrayList<>();
        today.add(new Furniture(30));
        today.add(new Electronics(8, true));
        today.add(new Electronics(2, false));
        int total = 0;
        for (DropOff item : today) {
            System.out.println(item);
            total += item.fee();
        }
        System.out.println("Total " + total);
    }
}
DropOff.java
public abstract class DropOff {
    private int kilos;

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

    public int getKilos() {
        return this.kilos;
    }

    public abstract int fee();

    @Override
    public String toString() {
        return this.kilos + " kg, fee " + this.fee();
    }
}
Furniture.java
public class Furniture extends DropOff {
    public Furniture(int kilos) {
        super(kilos);
    }

    @Override
    public int fee() {
        return 2 * this.getKilos();
    }
}
Electronics.java
public class Electronics extends DropOff {
    private boolean screen;

    public Electronics(int kilos, boolean screen) {
        super(kilos);
        this.screen = screen;
    }

    @Override
    public int fee() {
        if (this.screen) {
            return 20;
        }
        return 5;
    }
}
Output
30 kg, fee 60
8 kg, fee 20
2 kg, fee 5
Total 85

Your task

Challenge 1 of 3

Old tires are a drop-off too. DropOff.java is ready. Write the class Tires in Tires.java, as the diagram shows. Tires cost 4 dollars each.

The diagram as text
  • DropOff, an abstract class
    • private field kilos: int
    • public constructor DropOff(kilos: int)
    • public method getKilos(): int
    • public abstract method fee(): int
    • public method toString(): String
  • Tires, a class that extends DropOff
    • private field count: int
    • public constructor Tires(kilos: int, count: int)
    • public method fee(): int

The check runs:

DropOff tires = new Tires(36, 4);
System.out.println(tires);
System.out.println(tires.getKilos() + " " + tires.fee());

and expects:

36 kg, fee 16
36 16

Challenge 2

A music festival's program has this diagram, but the code doesn't match it in two places, and Main.java doesn't compile:

The diagram as text
  • Performer, an abstract class
    • private field name: String
    • public constructor Performer(name: String)
    • public method getName(): String
    • public abstract method slotMinutes(): int
    • public method toString(): String
  • Band, a class that extends Performer
    • private field members: int
    • public constructor Band(name: String, members: int)
    • public method slotMinutes(): int
  • Dj, a class that extends Performer
    • public constructor Dj(name: String)
    • public method slotMinutes(): int

A band plays 30 minutes plus 5 for each member, and a DJ plays 60 minutes. Fix Performer.java and Dj.java so that they match the diagram, and leave Main.java and Band.java as they are. The program should print:

The Low Tides, 50 min
Kora, 60 min
110 min in all

Challenge 3

A garden center delivers what its customers buy, by van or by bike. Write the three classes of this diagram, each in its own file:

The diagram as text
  • Delivery, an abstract class
    • private field address: String
    • public constructor Delivery(address: String)
    • public method getAddress(): String
    • public abstract method cost(): int
    • public method toString(): String
  • VanDelivery, a class that extends Delivery
    • private field pallets: int
    • public constructor VanDelivery(address: String, pallets: int)
    • public method cost(): int
  • BikeDelivery, a class that extends Delivery
    • public constructor BikeDelivery(address: String)
    • public method cost(): int
  • A van delivery costs 25 dollars, plus 15 for each pallet. A bike delivery costs 8.
  • Every delivery's toString returns 8 Hill Street: 55 dollars, with its own address and cost.

The check runs:

Delivery van = new VanDelivery("8 Hill Street", 2);
Delivery bike = new BikeDelivery("3 Pond Lane");
System.out.println(van);
System.out.println(bike);

and expects:

8 Hill Street: 55 dollars
3 Pond Lane: 8 dollars