Java Inheritance and Polymorphism - Practice Problem with Solution

Problem Statement

Assume, Highways department of Pakistan is installing a toll collection system on one of its major roads. Different toll booths deploy different policies to calculate toll. For example, trucks passing through a Ravi Toll Booth are required to pay a toll of PKR 5 per axle plus PKR 10 per half-ton of the loaded weight if its less than 30 ton and PKR 5 per half-ton for the weight above 30 tons. Trucks passing through Islamabad Toll Booth are required to pay PKR 8 per axle and PKR 12 per half-ton. You will design an object oriented program in Java that simulates the operation of the both tollbooths and different types of trucks.

Sample Scenario

To understand the problem statement let us imagine how such a toll collection system might work. A toll agent sits in a tollbooth that is equipped with a computer screen and a bar code reader. When a truck arrives at the booth, the agent scans a bar code on the windshield of the truck; it contains information about the truck, including its number of axles. The weight of the truck is obtained by scanning a bar code contained on the bill of lading presented by the driver.

In our case, the weight and number of trucks would be passed as command line argument (detail explained at end). Your program shall print the toll to be collected from driver when a truck arrive at a Ravi Toll Booth. It shall also print total toll collected and total number of trucks passed through the Ravi TollBooth at end. It shall also print information when same trucks pass through in same order from Islamabad Toll Booth.

At Ravi Toll Booth
Ford Truck Axles: 5  Total weight KG: 12500  Toll due: PKR 
Nissan Truck Axles: 8  Total weight KG: 35000  Toll due: PKR 
Ford Truck Axles: 6  Total weight KG: 20000  Toll due: PKR 
Daewoo Truck Axles: 10  Total weight KG: 40000  Toll due: PKR 
Nissan Truck Axles: 12  Total weight KG: 25000  Toll due: PKR 

Total Trucks Arrived: 5   Total Receipt: PKR 

At Islamabad Toll Booth
… 
…

This scenario will be simulated by the object oriented system that you will build. < > are place holders, you must print correct amount in it.

Primary Objects in the Problem Statement

The primary objects of the tollbooth model problem are the relevant noun phrases of the problem statement. In this case we list: trucks, tollbooth, axle, and weight, receipts. Of these, tollbooth and truck are the most important. Axles and weight are properties of a truck. Receipt is property of tollbooth. Therefore, we chose truck and tollbooth as our primary types.
Trucks Behaviors and Attributes

Toll depends on the number of axles and weight loaded on truck. Tollbooths need to get both of these from a truck. Therefore, a truck should keep track of number of axles it has, its total weight loaded. Truck shall allow other object to read these attributes values but not modify them. You must create separate class for each make.
TollBooth Behaviors and Attributes

The main behavior required of a tollbooth is the ability to calculate the toll due. So it shall store the total receipts and total number of trucks passed through it along with references of all those trucks (Hint: in ArrayList of Truck in TollBooth)

Directions to complete the assignment

1. Create and compile the two classes (Truck and TollBooth)
2. Create 3 classes that extends Truck e.g. FordTruck, NissanTruck, DaewooTruck. These classes should have the member variables (attributes) identified earlier. Carefully choose the access modifier and make sure that you take into account the fact that some variables change over time and others don't. Each Truck shall store its number of axles and loaded weight. It shall allow others to read both attributes but not change them. Each truck should have displayData method that shall be overridden by each type of truck. It shall print the make, total axles and loaded weight. E.g. Ford Truck Axles: 5 Total weight KG: 12500
3. Create a class RaviTollBooth that extends TollBooth. Both TollBoth shall keep track of a) the total number of trucks that have gone through it and b) total toll received. It shall also store reference of all trucks passed through it for auditing purpose.
4. When displayData method of TollBooth is called, it shall print the total number of trucks passed through it and total toll received. E.g. Total Trucks Arrived: 5 Total Receipt: PKR 54000
5. TollBooth should contain a method double calculateToll(Truck truck) that should be overridden by RaviTollBooth and IslamabadTollBooth to calculate toll using above mentioned rules for each booth. Override arrived(Truck truck) in both toll booths. When a truck arrives, this method shall be called to print the truck info using displayData method, it shall also display the toll due for that truck using calculateToll method of toll booth.

Using the TollBooth

Just to give you an idea how you would simulate passing through of truck trucks through a toll booth. Below is the code of main class. Please note, its’ not what you are supposed to write in your main file (see below requirements on how the program shall take input to understand in detail).

public class TestTollBooth {
    public static void main(String [] args){
 TollBooth booth = new RaviTollBooth();

 Truck ford = new FordTruck(5, 12000); // 5 axles and 12000 kilograms
 Truck nissan = new NissanTruck(2, 5000); // 2 axles and 5000kg 

 booth.arrived(ford);
        booth.arrived(nissan);
        booth.displayData();
    }
}

How I would check your program and how to pass input to program: Your program would be compiled and run by a pre-written Java program. I would check generated output on console to see whether you implemented toll calculation formulas correctly. So it’s REQUIRED that your program shall compile and run successfully and follow exactly the same names for different classes as explained in this document. Failure to compile or run would result into 0 marks and I would not check logic, because at this level you should be able to write programs that compile and run successfully. My program would go into each student submitted folder and execute following commands:

>javac TestTollBooth.java
>java TestTollBooth 1-5-12000 1-8-30000 2-8-25000 1-10-50000 3-10-30000 3-4-10000 3-6-20000

In above case, I have passed 7 trucks data. 1-5-12000 means make is Ford, Axles are 5 and load is 12000 KG. 2-8-25000 means make is Nissan, Axles are 8 and load is 25000 KG. You should process trucks in same order in which they arrive at tollbooth e.g. first command-line parameter is information of the truck that arrive first and so on. Above is just an example, user shall be able to use different combinations of makes, axles, load and number of trucks. Your program shall be dynamic to process all trucks.

Solution

package com.bitspedia.assignments.assignmnet2;

abstract class Truck {
    private final int axles;
    private double weight;

    public Truck(int axles, double weight) {
        this.axles = axles;
        this.weight = weight;
    }

    public int getAxles() {
        return axles;
    }

    public double getWeight() {
        return weight;
    }

    abstract public void displayData();
}


package com.bitspedia.assignments.assignmnet2;

class DaewooTruck extends Truck {
    private static final String name = "DaewooTruck";

    public DaewooTruck(int axles, double weight) {
        super(axles, weight);
    }

    public void displayData() {
        System.out.printf("%s Axles : %d Total Weight KG: %.2f ", name, getAxles(), getWeight());
    }
}


package com.bitspedia.assignments.assignmnet2;

class FordTruck extends Truck {
    private static final String name = "FordTruck";

    public FordTruck(int axles, double weight) {
        super(axles, weight);
    }

    public void displayData() {
        System.out.printf("%s   Axles : %d Total Weight KG: %.2f ", name, getAxles(), getWeight());
    }
}


package com.bitspedia.assignments.assignmnet2;

class NissanTruck extends Truck {
    private static final String name = "NissanTruck";

    public NissanTruck(int axles, double weight) {
        super(axles, weight);
    }

    public void displayData() {
        System.out.printf("%s Axles : %d Total Weight KG: %.2f ", name, getAxles(), getWeight());
    }
}


package com.bitspedia.assignments.assignmnet2;

import java.util.ArrayList;

abstract class TollBooth {
    protected ArrayList<Truck> trucksArrived = new ArrayList<>();
    private double totalToll;

    public void arrived(Truck truck) {
        double toll = calculateToll(truck.getAxles(), truck.getWeight());
        truck.displayData();
        System.out.printf("Toll Due: PKR <%.2f>\n", toll);
        addToll(toll);
        trucksArrived.add(truck);
    }

    protected void addToll(double toll) {
        this.totalToll += toll;
    }

    public double getTotalToll() {
        return totalToll;
    }

    abstract public double calculateToll(int axles, double weight);

    abstract public void displayData();

}

package com.bitspedia.assignments.assignmnet2;

class RaviTollBooth extends TollBooth {

    public double calculateToll(int axles, double weight) {
        double toll;
        toll = 5 * axles;
        weight = weight / 500;
        if (weight <= 60) {
            toll = toll + (10 * weight);
        } else {
            weight = weight - 60;
            toll = toll + (10 * 60) + (weight * 5);
        }
        return toll;
    }

    public void displayData() {
        System.out.printf("\nTotal Truck Arrived : %d   Total Receipt : PKR <%.2f>\n", trucksArrived.size(), getTotalToll());
    }
}


package com.bitspedia.assignments.assignmnet2;

class IslamabadTollBooth extends TollBooth {

    public double calculateToll(int axles, double weight) {
        double toll;
        toll = 10 * axles;
        weight = weight / 500;
        toll = toll + (12 * weight);
        return toll;
    }

    public void displayData() {
        System.out.printf("\nTotal Truck Arrived : %d   Total Receipt : PKR <%.2f>\n", trucksArrived.size(), getTotalToll());
    }
}


package com.bitspedia.assignments.assignmnet2;

import java.util.ArrayList;

public class TestTollBooth {

    public static void main(String[] args) {
        ArrayList<Truck> trucksList = makeTruckList(args);

        System.out.println("\nAt Ravi Toll Booth : \n");
        TollBooth tollBooth = new RaviTollBooth();
        for (Truck truck : trucksList)
            tollBooth.arrived(truck);
        tollBooth.displayData();

        System.out.println("\nAt Islamabad Toll Booth :\n");
        tollBooth = new IslamabadTollBooth();
        for (Truck truck : trucksList)
            tollBooth.arrived(truck);
        tollBooth.displayData();
    }

    public static ArrayList<Truck> makeTruckList(String[] commandLineArguments) {
        ArrayList<Truck> trucksList = new ArrayList<>();
        for (int i = 0; i < commandLineArguments.length; i++) {
            String data[] = commandLineArguments[i].split("-");
            String make = data[0];
            int axles = Integer.parseInt(data[1]);
            double weight = Double.parseDouble(data[2]);

            if (make.equals("1")) {
                trucksList.add(new FordTruck(axles, weight));
            } else if (make.equals("2")) {
                trucksList.add(new NissanTruck(axles, weight));
            } else if (make.equals("3")) {
                trucksList.add(new DaewooTruck(axles, weight));
            }
        }
        return trucksList;
    }
}

Above solution can be futher optimized in many ways. But I have make it simple by skipping many optimizations so that students are just starting with inheritance and polymorphims could easily understand. Following optimizations can be further performed:

  1. User interface for Truck and TollBooth 
  2. Shifting displayData from Truck subclasses to Truck class 
  3. Declaring name field in Truck rather than in each specific Truck class

Output of above TestTollBooth class when its run using below command:

java TestTollBooth 1-5-12000 1-8-30000 2-8-25000 1-10-50000 3-10-30000 3-4-10000 3-6-20000

At Ravi Toll Booth : 

FordTruck   Axles : 5 Total Weight KG: 12000.00 Toll Due: PKR <265 .00="">
FordTruck   Axles : 8 Total Weight KG: 30000.00 Toll Due: PKR <640 .00="">
NissanTruck Axles : 8 Total Weight KG: 25000.00 Toll Due: PKR <540 .00="">
FordTruck   Axles : 10 Total Weight KG: 50000.00 Toll Due: PKR <850 .00="">
DaewooTruck Axles : 10 Total Weight KG: 30000.00 Toll Due: PKR <650 .00="">
DaewooTruck Axles : 4 Total Weight KG: 10000.00 Toll Due: PKR <220 .00="">
DaewooTruck Axles : 6 Total Weight KG: 20000.00 Toll Due: PKR <430 .00="">

Total Truck Arrived : 7   Total Receipt : PKR <3595 .00="">

At Islamabad Toll Booth :

FordTruck   Axles : 5 Total Weight KG: 12000.00 Toll Due: PKR <338 .00="">
FordTruck   Axles : 8 Total Weight KG: 30000.00 Toll Due: PKR <800 .00="">
NissanTruck Axles : 8 Total Weight KG: 25000.00 Toll Due: PKR <680 .00="">
FordTruck   Axles : 10 Total Weight KG: 50000.00 Toll Due: PKR <1300 .00="">
DaewooTruck Axles : 10 Total Weight KG: 30000.00 Toll Due: PKR <820 .00="">
DaewooTruck Axles : 4 Total Weight KG: 10000.00 Toll Due: PKR <280 .00="">
DaewooTruck Axles : 6 Total Weight KG: 20000.00 Toll Due: PKR <540 .00="">

Total Truck Arrived : 7   Total Receipt : PKR <4758 .00="">

Comments

  1. This comment has been removed by the author.

    ReplyDelete
  2. sir in islamabad toll booth you have multiplied axles with 10 instead of 8 as given in question

    i hope this output will not affect our assingnmet

    ReplyDelete
  3. Needed to compose you a very little word to thank you yet again regarding the nice suggestions you’ve contributed here.
    Java Training in Marathahalli

    ReplyDelete
  4. I have to voice my passion for your kindness giving support to those people that should have guidance on this important matter.
    hadoop training in bangalore

    ReplyDelete

Post a Comment