package examples.supplierclasses;
/**
* This class represents an automobile. Notice that some of the variables are
* protected and some are private. These modifiers must be carefully chosen.
* For example, I chose final for all variables relating to the fuel level
* because I don't want clients (including subclasses) to be able to access
* these variables.
*
* But I'm not sure about make. So I left it protected so that subclasses can
* access this variable.
*/
public class Car {
/**
* Instance and class variables typically go at the start of the class body.
*/
/**
* Here are some constants (as indicated by final). These constants also
* belong to the class because they are declared static. Variables declared
* final are typically declared static too since there's no need to duplicate
* these values to each instance. These are declared public since they're
* meant to be used by clients when calling the setMake method.
*/
public static final int HONDA = 0;
public static final int CHEVROLET = 1;
public static final int FORD = 2;
/**
* The brand of this car. (e.g. Honda)
*/
protected int make = -1;
/**
* true when fuelAmount <= lowFuelThreshold, false otherwise
*/
private boolean lowFuel;
/**
* When fuel amount is less than or equal to this amount, fuelLow is set
* to true.
*/
private float lowFuelThreshold;
/**
* Miles per gallon of this vehicle.
*/
private float mpg;
/**
* Amount of gas in gallons that this car's tank current contains.
*/
private float fuelAmount;
/**
* A no-argument constructor. Initializes variables with default values.
*/
public Car() {
fuelAmount = 10;
mpg = 22;
lowFuelThreshold = 2;
lowFuel = false;
} // end constructor
/**
* Notice that the constructor is "overloaded." There are multiple
* constructors and client classes can use any one of them.
*/
public Car(float fuelAmount, float mpg, float lowFuelThreshold) {
// I have to use "this" here since the formal parameter fuelAmount, shadows
// my instance variable of the same name
this.fuelAmount = fuelAmount;
this.mpg = mpg;
this.lowFuelThreshold = lowFuelThreshold;
// it's possible that we start in a low-fuel condition; test it here
lowFuel = fuelAmount <= lowFuelThreshold;
} // end constructor
/**
* Drive the car the distance indicated by miles. The return value of this
* method is a boolean that indicates if this operation was successful (i.e.
* if there was enough fuel to go the distance).
*/
public boolean drive(int miles) {
// calculate how many gallons it will take to go the distance in miles;
// gallonsRequired is a "local" variable; it exists only during the
// execution of this method (i.e. its lifetime)
float gallonsRequired = miles * (1 / mpg);
// if we have enough fuel, deduct gallons from current amount, check for low
// fuel, and return true; otherwise, return false
if (gallonsRequired <= fuelAmount) {
fuelAmount -= gallonsRequired;
// check for low fuel
if (fuelAmount <= lowFuelThreshold) {
lowFuel = true;
}
return true;
}
else {
return false;
}
} // end method drive
/**
* setMake is an accessor method. In this case it provides write-only access.
* The items inside the parentheses are referred to as formal parameters.
*/
public void setMake(int make) {
this.make = make;
} // end method setMake
/**
* toString method is overridden. In other words, we've specified a different
* implementation of this method than our parent class did. We've used
* StringBuffer to reduce the amount of intermediate strings created while
* creating the string representation of this object.
*
* "FuelAmount: " is a string literal and "+" is the concatentation operator
* when dealing with strings.
*/
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("FuelAmount: " + fuelAmount);
buf.append(", LowFuel: " + lowFuel);
return buf.toString();
} // end method toString
/**
* Since this class contains a main method, it is runnable. The code inside
* main can be used for quick testing of a class.
*/
public static void main(String[] args) {
// use the new operator in conjunction with the constructor and
// bind the object to the variable c1 that is declared to by type Car
Car c1 = new Car(9, 15.3f, 3);
// call the setMake method and use the static member of the Car class as an
// argument
c1.setMake(Car.HONDA);
// print to the screen the state of the car's fuel
System.out.println("State of car before driving\n" + c1);
// call the drive method on the object bound to c1
c1.drive(120);
// print ending state; note: System.out.println uses our toString method to
// produce its output
System.out.println("State of car after driving\n" + c1);
// array to hold 3 Car instances
Car[] fleet = new Car[3];
// create new Car instances and bind to each array slot
for (int i = 0; i < fleet.length; i++) {
fleet[i] = new Car(); // using no-arg constructor
}
// the drive method returns a boolean value that represents the success of
// the drive operation; each successX is a local variable since each is
// declared inside the method body
boolean success0 = fleet[0].drive(300);
boolean success1 = fleet[1].drive(180);
boolean success2 = fleet[2].drive(4);
System.out.println("Car #1 successfully drove 300 miles: " + success0);
System.out.println("Car #2 successfully drove 180 miles: " + success1);
System.out.println("Car #3 successfully drove 4 miles: " + success2);
} // end method main
} // end class Car