Java Arena
Step 4 of 4

Choosing a design, and the end of part 9

This last step of part 9 puts the pieces together: first how to choose between them when you design classes of your own, then a look back at the whole part.

extends, abstract, or an interface?

Module 34 asked "is a, or has a?", and module 35 compared interfaces with abstract classes. With whole hierarchies in view, the choices look like this, with this module's examples:

When Use Example
Every X is a Y, and should get Y's code and data class X extends Y A Taxi is a Car, and gets its plate and its toll rule
Shared code, but no objects of the general kind an abstract class Employee keeps the name and the toString, and leaves monthlyPay() to each kind
Classes share an ability, but no code, or aren't otherwise related an interface Taxis and trucks are Commercial, and plain cars aren't
One class needs several roles one superclass, and any number of interfaces Bat extends Enemy implements Flying

For the types of variables, parameters and lists, pick the most general type that has everything the code needs. Payroll takes any Employee, a company's bill needs only Commercial, and step 2's spear only needs to know whether an enemy is Flying. Code written in that way works with more classes, including ones that don't exist yet, like the interns of step 3.

The end of part 9

This step ends the material of the MOOC's ninth part. Module 34 started from the class Object, which every class extends, and built classes on other classes with extends: super(...) for the superclass's constructor, overriding with @Override and super.method(), protected, "is a or has a", and abstract classes. Module 35 brought interfaces, lists of methods that a class promises with implements, used as the types of variables, parameters, return values and lists, and Java's own List, Map, Set and Collection. This module put them together. An object has every type of its hierarchy, instanceof asks which, and a cast gives a reference of the more specific type. A program built on a general type works with every kind of object, even kinds added later. Part 10 comes next, starting with streams and lambdas. Part 9 ends with the MOOC's summary page on its own site.

Your task

Challenge 1 of 3

The game gets hot-air balloons that drift across the sky. A balloon flies, but it isn't an enemy: it has no health, and nobody fights it. So Balloon implements Flying and has no extends: its only superclass is Object. Flying.java, Enemy.java and Bat.java are step 2's. Write:

  • in Balloon.java, the class Balloon, with a constructor Balloon(String color, int altitude), the method altitude() from Flying, and a toString that returns the color and the word balloon, like red balloon
  • in Main.java, the method lowest(ArrayList<Flying> flyers), which returns the flyer with the lowest altitude, the first of them when several are equally low, or null for an empty list

The check runs the following. A bat prints as every Enemy does, with its name and its health:

ArrayList<Flying> sky = new ArrayList<>();
sky.add(new Bat("Squeak", 9));
sky.add(new Balloon("red", 40));
sky.add(new Balloon("green", 6));
sky.add(new Bat("Flit", 12));
System.out.println(sky);
System.out.println(lowest(sky));

and expects:

[Squeak (8), red balloon, green balloon, Flit (8)]
green balloon

Challenge 2

The toll booth from step 1, with step 1's TankerTruck, which pays 10 more than a Truck. What does this program print?

Challenge 3

To end part 9: the toll booth's records, which bring together a class hierarchy, an interface, instanceof, and a hash map from part 8. Vehicle.java, Truck.java and Commercial.java are step 1's. Write:

  • In Van.java, the class Van. A delivery van is a Vehicle, and it works for a company. Its constructor is Van(String plate, String company), it pays a toll of 7, and it's Commercial.
  • In TollBooth.java:
    • the constructor,
    • pass(Vehicle vehicle), which records a vehicle going through the booth,
    • total(), which returns all the tolls paid so far, added up,
    • billFor(String company), which returns the tolls of that company's vehicles added up, or 0 for a company with none,
    • companies(), which returns a new list of the companies that have a bill, each once, in alphabetical order.

A HashMap<String, Integer> from a company to its bill is one good way to keep the bills. Main.java is a test drive, and it prints:

49
21
0
[Birch Haulage, Nordic Freight, Swift Parcels]