4.3. Extending Interfaces
Interfaces can be extended using the extends keyword. Interfaces, unlike classes, can extend more than one
other interface:
public interface SerializableRunnable
extends java.io.Serializable, Runnable
{
// ...
}
The SerializableRunnable interface extends both java.io.Serializable and Runnable,
which means that all methods and constants defined by those interfaces are now part of the
SerializableRunnable contract, together with any new methods and constants it defines. The
interfaces that are extended are the superinterfaces of the new interface and the new interface is a subinterface
of its superinterfaces.
Because interfaces support multiple inheritance, the inheritance graph can contain multiple paths to the same
superinterface. This means that constants and methods can be accessed in different ways. However, because
interfaces define no implementation of methods, and provide no per-object fields, there are no issues
regarding the semantics of this form of multiple inheritance.
4.3.1. Inheriting and Hiding Constants
An extended interface inherits all the constants declared in its superinterfaces. If an interface declares a
constant of the same name as an inherited constant, regardless of their types, then the new constant hides the
inherited one; this is the same hiding of fields described in "Hiding Fields" on page 86. In the subinterface and
in any object implementing the subinterface, any reference to the constant using its simple name will refer to
the constant defined in the subinterface. The inherited constant can still be accessed with the qualified name of
the constant, that is, the interface name followed by dot and then the constant namethe usual way of referring
to static members.
interface X {
int val = 1;
}
interface Y extends X {
int val = 2;
int sum = val + X.val;
}
Interface Y has two constants: val and sum. From inside Y, to refer to the hidden val in its superinterface
you must qualify it as X.val. Externally, you can access the constants of Y by using the normal static forms
of Y.val and Y.sum, and of course you can access X's val constant by using X.val.
These rules are, of course, identical to those concerning the inheritance of static fields in classes.
When a class implements Y you can access the constants in Y as though they were constants declared in the
class. For example, given
class Z implements Y { }