Spec-Zone .ru
спецификации, руководства, описания, API
|
ГЛАВА 9
Интерфейсное объявление представляет новый ссылочный тип, элементы которого являются константами и абстрактными методами. У этого типа нет никакой реализации, но иначе несвязанные классы могут реализовать его, обеспечивая реализации для ее абстрактных методов.
Программы Java могут использовать интерфейсы, чтобы сделать это ненужным для связанных классов, чтобы совместно использовать общий абстрактный суперкласс или добавить методы к Object
.
Интерфейс, как могут объявлять, является прямым расширением одного или более других интерфейсов, означая, что он неявно определяет все абстрактные методы и константы интерфейсов, которые он расширяет, за исключением любых констант, которые он может скрыть.
Класс, как могут объявлять, непосредственно реализует один или более интерфейсов, означая, что любой экземпляр класса реализует все абстрактные методы, определенные интерфейсом или интерфейсами. Класс обязательно реализует все интерфейсы, которые делают его прямые суперклассы и прямые суперинтерфейсы. Это (многократное) интерфейсное наследование позволяет объектам поддерживать (многократные) общие поведения, не совместно используя реализации.
Переменная, чья объявленный типом интерфейсный тип, может иметь как его значение ссылка на любой объект, который является экземпляром класса, который, как объявляют, реализовывал указанный интерфейс. Не достаточно, что класс, оказывается, реализует все абстрактные методы интерфейса; класс или один из его суперклассов, как должны фактически объявлять, реализуют интерфейс, или иначе класс, как полагают, не реализует интерфейс.
InterfaceDeclaration:Ошибка времени компиляции происходит, если Идентификатор, называя интерфейс появляется как имя какого-либо другого класса или интерфейса в том же самом пакете. Ошибка времени компиляции также происходит, если Идентификатор, называя интерфейс появляется как имя, которым класс или интерфейс должны быть известны через объявление единственного импорта типа (§7.5.1) в единице компиляции, содержащей интерфейсное объявление. В примере:
InterfaceModifiersoptinterface
Identifier
ExtendsInterfacesoptInterfaceBody
ошибка времени компиляции происходит потому что a
class Point { int x, y; }
interface Point { void move(int dx, int dy); }
class
и interface
в том же самом пакете не может иметь того же самого имени. InterfaceModifiers:Модификатор доступа
InterfaceModifier
InterfaceModifiers
InterfaceModifier InterfaceModifier: one of
public abstract
public
обсуждается в §6.6. Ошибка времени компиляции происходит, если тот же самый модификатор появляется не раз в интерфейсном объявлении. abstract
. Этот модификатор является устаревшим и не должен использоваться в новых программах Java. extends
пункт обеспечивается, тогда объявляемый интерфейс расширяет каждый из других именованных интерфейсов и поэтому наследовал методы и константы каждого из других именованных интерфейсов. Эти другие именованные интерфейсы являются прямыми суперинтерфейсами объявляемого интерфейса. Любой класс это implements
объявленный интерфейс, как также полагают, реализует все интерфейсы что этот интерфейс extends
и это доступно для класса. ExtendsInterfaces:Следующее повторяется от §4.3, чтобы сделать представление здесь более четким:
extends
InterfaceType
ExtendsInterfaces,
InterfaceType
InterfaceType:Каждый InterfaceType в
TypeName
extends
пункт интерфейсного объявления должен назвать доступный интерфейсный тип; иначе ошибка времени компиляции происходит.Ошибка времени компиляции происходит, если есть зацикливание так, что, интерфейс прямо или косвенно расширяет себя.
Нет никакого аналога класса Object
для интерфейсов; то есть, в то время как каждый класс является расширением класса Object
, нет никакого единственного интерфейса, которого все интерфейсы являются расширениями.
Суперинтерфейсное отношение является переходным закрытием прямого суперинтерфейсного отношения. Интерфейсный K является суперинтерфейсом интерфейса I, если любое из следующего является истиной:
InterfaceBody:Контекст имени элемента, объявленного в интерфейсном типе, является всем телом интерфейсного описания типа.
{
InterfaceMemberDeclarationsopt}
InterfaceMemberDeclarations:
InterfaceMemberDeclaration
InterfaceMemberDeclarationsInterfaceMemberDeclaration InterfaceMemberDeclaration:
ConstantDeclaration
AbstractMethodDeclaration
public
. Они доступны вне пакета, где интерфейс объявляется, если интерфейс также объявляется public
и пакет, содержащий интерфейс, доступен как описано в §7.1. Интерфейс наследовался от интерфейсов, которые он расширяет, все элементы тех интерфейсов, за исключением полей, которые он скрывает и методы, которые он переопределяет.
ConstantDeclaration:Каждое полевое объявление в теле интерфейса неявно
ConstantModifiersType
VariableDeclarator ConstantModifiers: one of
public static final
public
, static
, и final
. Это разрешается, но строго обескураживается как стиль, чтобы избыточно определить любые из этих модификаторов для таких полей.
Объявление константы в интерфейсе не должно включать ни один из модификаторов synchronized
, transient
, или volatile
, или ошибка времени компиляции происходит.
Для интерфейса возможно наследовать больше чем одно поле с тем же самым именем (§8.3.3.3). Такая ситуация сам по себе не вызывает ошибку времени компиляции. Однако, любая попытка в пределах тела интерфейса, чтобы обратиться к любому полю его простым именем приведет к ошибке времени компиляции, потому что такая ссылка неоднозначна.
Могло бы быть несколько путей, которыми то же самое полевое объявление могло бы быть наследовано от интерфейса. В такой ситуации поле, как полагают, наследовано только однажды, и это может быть упомянуто его простым именем без неоднозначности.
Ошибка времени компиляции происходит, если выражение инициализации для интерфейсного поля содержит ссылку простым именем к тому же самому полю или к другому полю, объявление которого происходит дословно позже в том же самом интерфейсе. Таким образом:
interface Test { float f = j; int j = 1; int k = k+1; }причины две ошибки времени компиляции, потому что
j
упоминается в инициализации f
прежде j
объявляется и потому что инициализация k
обращается к k
непосредственно. (Одна тонкость вот то, что во время выполнения, fields
это инициализируется с постоянными величинами времени компиляции, инициализируются сначала. Это применяется также к static
final
поля в классах (§8.3.2.1). Это означает, в частности что у этих полей, как никогда будут наблюдать, не будет своих начальных значений по умолчанию (§4.5.4), даже окольными программами. См. §12.4.2 и §13.4.8 для большего количества обсуждения.)
Если ключевое слово this
(§15.7.2) или ключевое слово super
(15.10.2, 15.11), происходит в выражении инициализации для поля интерфейса, затем ошибка времени компиляции происходит.
interface BaseColors { int RED = 1, GREEN = 2, BLUE = 4; }интерфейс
interface RainbowColors extends BaseColors { int YELLOW = 3, ORANGE = 5, INDIGO = 6, VIOLET = 7; }
interface PrintColors extends BaseColors { int YELLOW = 8, CYAN = 16, MAGENTA = 32; }
interface LotsOfColors extends RainbowColors, PrintColors { int FUCHSIA = 17, VERMILION = 43, CHARTREUSE = RED+90; }
LotsOfColors
наследовал два названные поля YELLOW
. Это в порядке, пока интерфейс не содержит ссылки простым именем к полю YELLOW
. (Такая ссылка могла произойти в пределах переменного инициализатора для поля.) Даже если интерфейс PrintColors
должны были дать значение 3
к YELLOW
вместо значения 8
, ссылка на поле YELLOW
в пределах интерфейса LotsOfColors
все еще считался бы неоднозначным.
В примере в предыдущем разделе, полях RED
, GREEN
, и BLUE
наследованы интерфейсом LotsOfColors
больше чем одним способом, через интерфейс RainbowColors
и также через интерфейс PrintColors
, но ссылка на поле RED
в интерфейсе LotsOfColors
не считается неоднозначным потому что только одно фактическое объявление поля RED
включается.
AbstractMethodDeclaration:Модификатор доступа
AbstractMethodModifiersoptResultType
MethodDeclarator
Throwsopt
;
AbstractMethodModifiers:
AbstractMethodModifier
AbstractMethodModifiersAbstractMethodModifier AbstractMethodModifier: one of
public abstract
public
обсуждается в §6.6. Ошибка времени компиляции происходит, если тот же самый модификатор появляется не раз в абстрактном объявлении метода. Каждое объявление метода в теле интерфейса неявно abstract
, таким образом, его тело всегда представляется точкой с запятой, не блоком. Для совместимости с более старыми версиями Java это разрешается, но обескураживается, как стиль, чтобы избыточно определить abstract
модификатор для методов объявляется в интерфейсах.
Каждое объявление метода в теле интерфейса неявно public
. Это разрешается, но строго обескураживается как стиль, чтобы избыточно определить public
модификатор для интерфейсных методов.
Отметьте, что метод, объявленный в интерфейсе, не должен быть объявлен static
, или ошибка времени компиляции происходит, потому что в Java static
методы не могут быть abstract
.
Отметьте, что метод, объявленный в интерфейсе, не должен быть объявлен native
или synchronized
, или ошибка времени компиляции происходит, потому что те ключевые слова описывают свойства реализации, а не интерфейсные свойства. Однако, метод, объявленный в интерфейсе, может быть реализован методом, который объявляется native
или synchronized
в классе, который реализует интерфейс.
Отметьте, что метод, объявленный в интерфейсе, не должен быть объявлен final
или ошибка времени компиляции происходит. Однако, метод, объявленный в интерфейсе, может быть реализован методом, который объявляется final
в классе, который реализует интерфейс.
Если объявление метода в интерфейсе переопределяет объявление метода в другом интерфейсе, ошибка времени компиляции происходит, если у методов есть различные типы возврата или если у Вас есть тип возврата, и другой void
. Кроме того у объявления метода не должно быть a throws
пункт, который конфликтует (§8.4.4) с тем из любого метода, который это переопределяет; иначе, ошибка времени компиляции происходит.
Методы переопределяются на основе подписи подписью. Если, например, интерфейс объявляет два public
методы с тем же самым именем, и подынтерфейс переопределяют одного из них, подынтерфейс все еще наследовал другой метод.
Интерфейс наследовал от его прямых суперинтерфейсов все методы суперинтерфейсов, которые не переопределяются объявлением в интерфейсе.
Для интерфейса возможно наследовать больше чем один метод с той же самой подписью (§8.4.2). Такая ситуация сам по себе не вызывает ошибку времени компиляции. Интерфейс, как полагают, наследовал все методы. Однако, ошибка времени компиляции происходит, если для каких-либо двух таких наследованных методов у или их есть различные типы возврата, или у каждого есть тип возврата, и другой void
. ( throws
пункты не вызывают ошибки в этом случае.)
Могло бы быть несколько путей, которыми то же самое объявление метода наследовано от интерфейса. Этот факт не вызывает трудности и никогда себя результаты в ошибке времени компиляции.
throws
пункты двух методов с тем же самым именем, но различными подписями. abstract
и таким образом не содержите реализацию. Обо все, что может быть выполнено объявлением метода переопределения, кроме подтвердить сигнатуру метода, должно ограничить исключения, которые могли бы быть выданы реализацией метода. Вот изменение примера, показанного в §8.4.3.1: class BufferEmpty extends Exception { BufferEmpty() { super(); } BufferEmpty(String s) { super(s); } }
class BufferError extends Exception { BufferError() { super(); } BufferError(String s) { super(s); } }
public interface Buffer { char get() throws BufferEmpty, BufferError; }
public interface InfiniteBuffer extends Buffer { char get() throws BufferError; // override }
interface PointInterface { void move(int dx, int dy); }имя метода
interface RealPointInterface extends PointInterface { void move(float dx, float dy); void move(double dx, double dy); }
move
перегружается в интерфейсе RealPointInterface
с тремя различными подписями, двумя из них объявленный и один наследованный. Любой класс, который реализует интерфейс RealPointInterface
должен обеспечить реализации всех трех сигнатур методов.
Содержание | Предыдущий | Следующий | Индекс
Спецификация языка Java (HTML, сгенерированный Блинчиком "сюзет" Pelouch 24 февраля 1998)
Авторское право © Sun Microsystems, Inc 1996 года. Все права защищены
Пожалуйста, отправьте любые комментарии или исправления к doug.kramer@sun.com