Final Declarations – Object-Oriented Programming

Final Declarations – Object-Oriented Programming

5.5 Final Declarations

The keyword final can be used in the following contexts in Java:

  • Declaring final classes (p. 225)
  • Declaring final members in classes (p. 226), and in enum types (p. 294)
  • Declaring final local variables in methods and blocks (p. 231)
  • Declaring final static variables in interfaces (p. 254)

Final Classes

A class can be declared final to indicate that it cannot be extended—that is, one cannot define subclasses of a final class. In other words, the class behavior cannot be changed by extending the class. This implies that one cannot override or hide any methods declared in such a class. Its methods behave as final methods (p. 226). A final class marks the lower boundary of its implementation inheritance hierarchy.

A concrete class is a class that has only concrete methods—that is, methods that are non-abstract, and therefore have an implementation. Only a concrete class can be declared final. If it is decided that the class TubeLight at (12) in Example 5.9 may not be extended, it can be declared final. Any attempt to specify the class name TubeLight in an extends clause will result in a compile-time error.

Click here to view code image

final class TubeLight extends Light {               // (12)
  // …
}

class NeonLight extends TubeLight {                 // Compile-time error!
  // …
}

A final class must be complete, whereas an abstract class is considered incomplete. Classes, therefore, cannot be both final and abstract at the same time. Interfaces are implicitly abstract, and therefore cannot be declared as final. A final class and an interface with only abstract methods represent two diametrical strategies when it comes to providing an implementation: the former with all the methods implemented and the latter with none. An abstract class or an interface with partial implementation represents a compromise between these two strategies.

The Java SE Platform API includes many final classes—for example, the java.lang.String class and the wrapper classes for primitive values.