Abstract Classes

Abstract Classes

In the shipping example, suppose that the system needed to supply a weekly report that lists each vehicle in the company’s fleet and the fuel needs for their upcoming trips. Assume that the Shipping System has a ShippingMain class that populates the company’s vehicle fleet list and generates the Fuel Needs report.

Figure shows the UML model of the company and its heterogeneous collection of vehicles (the fleet association).

The ShippingMain program shows the initialization of an example fleet.

1 public class ShippingMain {

2 public static void main(String[] args) {

3 Company c = new Company();


5 // populate the company with a fleet of vehicles

6 c.addVehicle( new Truck(10000.0) );

7 c.addVehicle( new Truck(15000.0) );

8 c.addVehicle( new RiverBarge(500000.0) );

9 c.addVehicle( new Truck(9500.0) );

10 c.addVehicle( new RiverBarge(750000.0) );


12 FuelNeedsReport report = new FuelNeedsReport(c);

13 report.generateText(System.out);

14 }

15 }

You should write the report code as follows:

1 public class FuelNeedsReport {

2 private Company company;


4 public FuelNeedsReport(Company company) {

5 this.company = company;

6 }


8 public void generateText(PrintStream output) {

9 Vehicle1 v;

10 double fuel;

11 double total_fuel = 0.0;


13 for ( int i = 0; i < company.getFleetSize(); i++ ) {

14 v = company.getVehicle(i);


16 // Calculate the fuel needed for this trip

17 fuel = v.calcTripDistance() / v.calcFuelEfficency();


19 output.println(“Vehicle ” + v.getName() + ” needs “

20 + fuel + ” liters of fuel.”);

21 total_fuel += fuel;

22 }

23 output.println(“Total fuel needs is ” + total_fuel + ” liters.”);

24 }

25 }

The calculation for the fuel requirements is the trip distance (in kilometers) divided by the vehicle’s fuel efficiency (in kilometers per liter).

The Problem

The calculations to determine fuel efficiency of a truck as compared with a river barge might differ radically. The Vehicle class can not supply these two methods, but its subclasses (Truck and RiverBarge) can.

The Solution

The Java programming language enables a class designer to specify that a superclass declares a method that does not supply an implementation. This is called an abstract method. The implementation of this method is supplied by the subclasses. Any class with one or more abstract methods is called an abstract class (see Figure).


Figure presents a UML model of the solution. Vehicle is an abstract class with two public, abstract methods.

Note – UML uses the italic font to indicate abstract elements in a class diagram. You may also indicate an abstract class with the {abstract} constraint flag in the name compartment.

The Java compiler prevents you from instantiating an abstract class. For example, the statement new Vehicle() is illegal.

The declaration of the Vehicle class is:

1 public abstract class Vehicle {

2 public abstract double calcFuelEfficiency();

3 public abstract double calcTripDistance();

4 }

The Truck class must create an implementation:

1 public class Truck extends Vehicle {

2 public Truck(double maxLoad) {…}

3 public double calcFuelEfficiency() {

4 // calculate the fuel consumption of a truck

5 }

6 public double calcTripDistance() {

7 // calculate the distance of this trip on highway

8 }

9 }

The RiverBarge class must create an implementation:

1 public class RiverBarge extends Vehicle {

2 public RiverBarge(double maxLoad) {…}

3 public double calcFuelEfficiency() {

4 // calculate the fuel consumption of a river barge

5 }

6 public double calcTripDistance() {

7 // calculate the distance of this trip along rivers

8 }

9 }

However, abstract classes can have data attributes, concrete methods, and constructors. For example, the Vehicle class might include load and maxLoad attributes and a constructor to initialize them. It is a good practice to make these constructors protected rather than public, because it is only meaningful for these constructors to be invoked by the subclasses of the abstract class. Making these constructors protected makes it more obvious to the programmer that the constructor should not be called from arbitrary classes.