Abstract Methods in Classes
In this subsection we discuss in more detail declaring and overriding abstract methods in classes.
Declaring an abstract Method
An abstract method in an abstract class has the following syntax:
access_modifier
abstract
return_type method_name
(
formal_parameter_list
)
throws_clause
;
An abstract method does not have an implementation; that is, no method body is defined for an abstract method, and only the method header is provided in the class declaration. The keyword abstract is mandatory in the header of an abstract method declared in a class. Its class is then incomplete and must be explicitly declared as abstract. Subclasses of an abstract class must then override the abstract method to provide the method implementation; otherwise, they must also be declared as abstract.
Overriding an abstract Method
When overriding an abstract method from the superclass, the notation @Override should always be used in the overriding method in the subclass. The compiler will issue an error if the override criteria are not satisfied.
The accessibility of an abstract method declared in a top-level class cannot be private, as subclasses would not be able to override the method and provide an implementation. Thus an abstract method in a top-level class can only have public, protected, or package accessibility.
In Example 5.8, the abstract instance method in the abstract superclass Light has the following declaration:
protected abstract double energyCost(int noOfHours) // (2) Method header
throws InvalidHoursException; // No method body
It has protected access and has type double as the return type. Its method signature is energyCost(int), and it throws the checked InvalidHoursException.
The implementation of the abstract method in the subclass TubeLight has the following declaration:
@Override public double energyCost(int noOfHours) { // (3)
return 0.15 * noOfHours;
}
It has public access and has type double as the return type. Its method signature is energyCost(int), and it has no throws clause. Widening the access to public access and throwing no checked exceptions are allowed according to the override criteria.
Since an abstract method must be overridden to provide an implementation, only an instance method can be declared as abstract. Since static methods cannot be overridden, declaring an abstract static method makes no sense, and the compiler will report an error.
An abstract method can be overloaded just like a normal method. The following method declaration in either the superclass or the subclass overloads the method named energyCost, as it has a different signature: energyCost().
public double energyCost() { // Overloaded
return 1.75;
}
If an attempt to override or overload an abstract method fails, the compiler will issue an error. If either of these two methods is declared in a subclass of the Light class, the compiler will issue an error.
@Override
double energyCost(int numOfHours) { // Not overridden! Narrows accessibility!
return 2.0 * numOfHours;
}
public Double energyCost(int numOfHours) { // Not overloaded! Duplicate method!
return 3.5 * numOfHours;
}
An abstract method or a non-final concrete method in a class can be overridden by an abstract method in a subclass. This is governed by the same rules for method overriding.
A method cannot be both final and abstract—that would be a contradiction in terms: A final method cannot be overridden, but an abstract method must be overridden to provide an implementation.
For a discussion of abstract methods in top-level interfaces, see §5.6, p. 240. Abstract methods can also be declared in an enum type, if the enum type contains constant-specific class bodies that implement these methods (p. 294).