
How it works...
Whether the Engine class is implemented as an inner class or a method-local inner class, the test code looks the same:
public static void main(String arg[]) {
double timeSec = 10.0;
int engineHorsePower = 246;
int vehicleWeightPounds = 4000;
Vehicle vehicle =
new Vehicle(vehicleWeightPounds, engineHorsePower);
System.out.println("Vehicle speed (" + timeSec + " sec) = "
+ vehicle.getSpeedMph(timeSec) + " mph");
}
If we run the preceding program, we get the same output:

Now, let's assume that we need to test a different implementation of the getSpeedMph() method:
public double getSpeedMph(double timeSec){ return -1.0d; }
If this speed-calculation formula does not make sense to you, you are correct, it does not. We did it to make the result predictable and different from the result of the previous implementation.
There are many ways to introduce this new implementation. We can change the code of the getSpeedMph(double timeSec) method in the Engine class, for example. Or, we can change the implementation of the same method in the Vehicle class.
In this recipe, we will do this by using the third type of inner class, called the anonymous inner class. This approach is especially handy when you want to write as little new code as possible, or you want to quickly test the new behavior by temporarily overriding the old one. The usage of an anonymous class would then look like the following:
public static void main(String... arg) {
double timeSec = 10.0;
int engineHorsePower = 246;
int vehicleWeightPounds = 4000;
Vehicle vehicle =
new Vehicle(vehicleWeightPounds, engineHorsePower) {
public double getSpeedMph(double timeSec){
return -1.0d;
}
};
System.out.println("Vehicle speed (" + timeSec + " sec) = "
+ vehicle.getSpeedMph(timeSec) + " mph");
}
If we run this program, this would be the result:

As you can see, the anonymous class implementation has overridden the Vehicle class implementation. The new anonymous class has only one method in it—the getSpeedMph() method which returns the hardcoded value. But we could override other methods of the Vehicle class or add new ones too. We just wanted to keep the example simple for demonstration purposes.
By definition, an anonymous inner class has to be an expression that is part of a statement that ends (as any statement) with a semicolon. Such an expression is composed of the following parts:
- The new operator
- The name of the implemented interface or extended class followed by parentheses, (), that represents the default constructor or a constructor of the extended class (the latter is our case, with the extended class being Vehicle)
- The class body with methods
Like any inner class, an anonymous inner class can access any member of the enclosing class with a caveat—to be used by an inner anonymous class, the fields of the enclosing class have to be either declared final or become final implicitly, which means that their values cannot be changed. A good modern IDE will warn you about the violation of this constraint if you try to change such a value.
Using these features, we can modify our sample code and provide more input data for the newly implemented getSpeedMph(double timeSec) method without passing them as method parameters:
public static void main(String... arg) {
double timeSec = 10.0;
int engineHorsePower = 246;
int vehicleWeightPounds = 4000;
Vehicle vehicle =
new Vehicle(vehicleWeightPounds, engineHorsePower){
public double getSpeedMph(double timeSec){
double v = 2.0 * engineHorsePower * 746 *
timeSec * 32.17 / vehicleWeightPounds;
return Math.round(Math.sqrt(v) * 0.68);
}
};
System.out.println("Vehicle speed (" + timeSec + " sec) = "
+ vehicle.getSpeedMph(timeSec) + " mph");
}
Notice that the timeSec, engineHorsePower, and vehicleWeightPounds variables are accessible by the getSpeedMph(double timeSec) method of the inner class and cannot be modified. If we run the preceding code, the result will be the same as before:

In the case of an interface with only one abstract method (called the functional interface), instead of an anonymous inner class, another construct can be used, called a lambda expression. It provides a shorter notation. We are going to discuss the functional interface and lambda expressions in Chapter 4, Going Functional.