I am currently attempting to refactor 2 sub classes into a super class. The sub classes are called Taxi
and Shuttle
and the superclass is called Vehicle
. I have moved the duplicate code in both and made the constructor in the subclasses call the method super as shown below but I keep getting the error message
Cannot Reference "ident" before supertype constructor has been called)
Why?
Here's Vehicle
public class Vehicle
{
// instance variables - replace the example below with your own
protected String ident;
// The Destination Of Taxi and Shuttle
protected String destination;
// The location of this shuttle.
protected String location;
/**
* Constructor for objects of class Vehicle
*/
public Vehicle(String id, String base)
{
// initialise instance variables
this.ident = id;
location = base;
destination = null;
}
/**
* Return the location of the shuttle.
* @return The location of the shuttle.
*/
public String getLocation()
{
return location;
}
/**
* Return the destination of the shuttle.
* @return The destination of the shuttle.
*/
public String getDestination()
{
return destination;
}
/**
* Return the ID of the shuttle.
* @return The ID of the shuttle.
*/
public String getIdent()
{
return ident;
}
}
Here's Taxi
public class Taxi extends Vehicle
{
// Whether it is free or not.
private boolean free;
/**
* Constructor for objects of class Taxi.
* @param base The name of the company's base.
* @param id This taxi's unique id.
*/
public Taxi(String id, String base)
{
super(ident);
free = true;
}
/**
* Book this taxi to the given destination.
* The status of the taxi will no longer be free.
* @param destination The taxi's destination.
*/
public void book(String destination)
{
setDestination(destination);
free = false;
}
/**
* Return the status of this taxi.
* @return The status.
*/
public String getStatus()
{
return vehicle.ident + " at " + location + " headed for " +
destination;
}
/**
* Indicate that this taxi has arrived at its destination.
* As a result, it will be free.
*/
public void signalArrival()
{
location = destination;
destination = null;
free = true;
}
}
Here's Shuttle
import java.util.ArrayList;
/**
* A shuttle.
* Shuttles have a unique ID, a location and a list of destinations.
* They operate a circular route.
*
* @author David J. Barnes
* @version 2016.12.04
*/
public class Shuttle extends Vehicle
{
private ArrayList<String> route;
// The destination number in route that the shuttle is
// currently headed for.
private int destinationNumber;
/**
* Constructor for objects of class Shuttle
* @param id This shuttle's unique id.
* @param route The route taken by this shuttle.
* The first entry is the starting location.
*/
public Shuttle(ArrayList<String> route)
{
super(ident);
setRoute(route);
}
/**
* Return the status of this shuttle.
* @return The status.
*/
public String getStatus()
{
return ident + " at " + location + " headed for " +
destination;
}
/**
* Indicate that this shuttle has arrived at its next destination.
*/
public void signalArrival()
{
location = destination;
setNextDestination();
}
/**
* Set the next destination of the shuttle.
*/
private void setNextDestination()
{
destinationNumber++;
if(destinationNumber >= route.size()) {
// End of the circular route.
// Start from the beginning again.
destinationNumber = 0;
}
setDestination(route.get(destinationNumber));
}
/**
* Set the route for this shuttle.
* @param route The circular list of destinations.
*/
private void setRoute(ArrayList<String> route)
{
if(route.size() < 2) {
throw new IllegalStateException("setRoute must have at least two destinations");
}
// Make a copy of the list parameter.
this.route = new ArrayList<String>();
this.route.addAll(route);
destinationNumber = 0;
location = route.get(destinationNumber);
setNextDestination();
}
}
Vehicle
doesn't have a public Vehicle(String id)
constructor, only a public Vehicle(String id, String base)
constructor .
The constructor of Taxi
should call the correct (existing) super-constructor.
Note that we will pass the local variable id
to the super constructor, passing to Vehicle
its own empty ident
variable would make no sense .
public Taxi(String id, String base)
{
super(id, base);
free = true;
}
The constructor of Shuttle
is missing an id
parameter (from its documentation), let's add it and use the first entry of the list as the base
parameter (again from its documentation) :
/**
* Constructor for objects of class Shuttle
* @param id This shuttle's unique id.
* @param route The route taken by this shuttle.
* The first entry is the starting location.
*/
public Shuttle(String id, ArrayList<String> route)
{
super(id,route.get(0));
setRoute(route);
}