5.6 Interfaces
An interface defines a contract for services that classes can implement. Objects of such classes guarantee that this contract will be honored.
Before diving into interfaces, an overview of the inheritance relationship between classes can be useful. The extends clause in a class definition only allows linear inheritance between classes—that is, a subclass can only extend one superclass. A superclass reference can refer to objects of its own type and of its subclasses strictly according to the linear inheritance hierarchy. Note that this inheritance relationship between classes comprises both inheritance of type (i.e., a subclass inherits the type of its superclass and can act as such) and inheritance of implementation (i.e., a subclass inherits methods and fields from its superclass). Since this relationship is linear, it rules out multiple inheritance of implementation, in which a subclass can inherit implementation directly from more than one direct superclass.
As we shall see in this section, interfaces not only allow new named reference types to be introduced, but their usage can result in both multiple inheritance of type and multiple inheritance of implementation. As we shall also see, multiple inheritance of type does not pose any problems, but multiple inheritance of implementation does and is disallowed by the compiler.
Defining Interfaces
A top-level interface has the following syntax:
access_modifier
interface
interface_name
optional_type_parameter_list
optional_extends_interface_clause
// Interface header
{ // Interface body
abstract_method_declarations
default_method_declarations
static_method_declarations
private_instance_method_declarations
private_static_method_declarations
constant_declarations
member_type_declarations
}
In the interface header, the name of the interface is preceded by the keyword interface. In addition, the interface header can specify the following information:
- The access modifier can be public or private. Lack of an access modifier implies package accessibility.
- The optional type parameter list specifies a comma-separated list of any formal type parameters enclosed by angle brackets (<>) for declaring a generic interface (§11.2, p. 572).
- The optional extends interface clause specifies a comma-separated list of any superinterfaces that the interface extends (p. 244).
The interface body can contain member declarations that include any of the following:
- Abstract method declarations (p. 240)
- Default method declarations (p. 246)
- Static method declarations (p. 251)
- Private instance and static method declarations (p. 252)
- Constant declarations (p. 254)
- Member type declarations (§9.1, p. 491)
An interface is abstract by definition, which means that it cannot be instantiated. Declaring an interface as abstract is superfluous and seldom done in practice. It is the only non-access modifier that can be specified for a top-level interface.
The member declarations can appear in any order in the interface body, which can be empty. Since interfaces are meant to be implemented by classes, interface members implicitly have public access and the public modifier can be omitted. The following declaration is an example of a bare-bones interface that has an empty body:
interface Playable { }
Interfaces with empty bodies can be used as markers to tag classes as having a certain property or behavior. Such interfaces are also called ability interfaces. The Java SE Platform API provides several examples of such marker interfaces—for example, java.lang.Cloneable, java.io.Serializable (§20.5, p. 1261), and java.util.EventListener. However, annotations (Chapter 25, p. 1555) are a better solution than marker interfaces for attaching metadata to class definitions.
Table 5.2 and Table 5.3 summarize the salient properties of member declarations that can be included in an interface, and which we will elaborate on in this section.
Table 5.2 Summary of Member Declarations in an Interface (Part I)
Member declarations | Abstract instance method | Default instance method | Static method | Private instance method | Private static method |
Access modifier: | Implicitly public | Implicitly public | Implicitly public | private mandatory | private mandatory |
Non-access modifier: | Implicitly abstract | default mandatory | static mandatory | None | static mandatory |
Implemented: | No | Yes | Yes | Yes | Yes |
Can be inherited: | If not overridden | If not overridden | No | No | No |
Table 5.3 Summary of Member Declarations in an Interface (Part II)
Member declarations | Constant | Member type declaration |
Access modifier: | Implicitly public | Implicitly public |
Non-access modifier: | Implicitly static and final | Implicitly static |
Implemented: | Yes | Yes |
Can be inherited: | If not hidden | If not hidden |