Toll Calculator (Polymorphism)
Problem
Write an abstract class Vehicle with an abstract method toll(distance). A Car pays 2 per km. A Truck pays a flat 50 plus 5 per km. A Bike pays 1 per km but at least 10. Every input line is: kind distance (kind is car, truck or bike). Print the toll of each line. The main loop must not use a switch on the kind after the objects are created; it just calls toll() on the object.
Constraints
- 1 <= lines <= 10^4
- 0 <= distance <= 10^6
Examples
Input
car 10 truck 10 bike 3
Output
20 100 10
Solutions
Polymorphism means that the same call (toll) does different things for different objects. The decision about the kind is made once, in the factory. When a new vehicle type arrives, we add a class and one line in the factory; the other code does not change.
/*
* Problem : Process lines.
* Input : Several lines.
* Output : One toll per line.
* Approach: Abstract class with subclasses.
* Time : O(n)
* Space : O(n)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// Step 1: The abstract class says that every vehicle can calculate a toll, but not how.
static abstract class Vehicle {
abstract long toll(long distance);
}
// Step 2: Every subclass gives its own rule for toll().
static class Car extends Vehicle {
@Override
long toll(long distance) {
return 2 * distance;
}
}
static class Truck extends Vehicle {
@Override
long toll(long distance) {
return 50 + 5 * distance;
}
}
static class Bike extends Vehicle {
@Override
long toll(long distance) {
return Math.max(10, distance);
}
}
// Step 3: A factory method creates the right object once. After that the caller only uses the Vehicle type.
static Vehicle create(String kind) {
if (kind.equals("car")) {
return new Car();
}
return kind.equals("truck") ? new Truck() : new Bike();
}
// This method solves the task. It receives the input and returns the answer.
static String[] solve(String[] lines) {
String[] output = new String[lines.length];
for (int i = 0; i < lines.length; i++) {
String[] part = lines[i].split(" ");
Vehicle vehicle = create(part[0]);
output[i] = String.valueOf(vehicle.toll(Long.parseLong(part[1])));
}
return output;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
java.util.List<String> all = new java.util.ArrayList<>();
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (!line.isEmpty()) {
all.add(line);
}
}
String[] lines = all.toArray(new String[0]);
System.out.println(String.join("\n", solve(lines)));
}
}
Hints (1)
- What is abstract about the method toll in Vehicle?