Spec-Zone .ru
спецификации, руководства, описания, API
|
Содержание | Предыдущий | Следующий | Индекс | Спецификация языка Java Второй Выпуск |
ГЛАВА 9
Интерфейсное объявление представляет новый ссылочный тип, элементы которого являются классами, интерфейсами, константами и абстрактными методами. У этого типа нет никакой реализации, но иначе несвязанные классы могут реализовать его, обеспечивая реализации для ее абстрактных методов.
Вложенный интерфейс является любым интерфейсом, объявление которого происходит в пределах тела другого класса или интерфейса. Высокоуровневый интерфейс является интерфейсом, который не является вложенным интерфейсом.
Эта глава обсуждает общую семантику всего верхнего уровня интерфейсов (§7.6) и вложенный (§8.5, §9.5). Детали, которые являются определенными для определенных видов интерфейсов, обсуждаются в разделах, выделенных этим конструкциям.
Программы могут использовать интерфейсы, чтобы сделать это ненужным для связанных классов, чтобы совместно использовать общий абстрактный суперкласс или добавить методы к Object
. Интерфейс, как могут объявлять, является прямым расширением одного или более других интерфейсов, означая, что он неявно определяет все типы элемента, абстрактные методы и константы интерфейсов, которые он расширяет, за исключением любых типов элемента и констант, которые он может скрыть.
Класс, как могут объявлять, непосредственно реализует один или более интерфейсов, означая, что любой экземпляр класса реализует все абстрактные методы, определенные интерфейсом или интерфейсами. Класс обязательно реализует все интерфейсы, которые делают его прямые суперклассы и прямые суперинтерфейсы. Это (многократное) интерфейсное наследование позволяет объектам поддерживать (многократные) общие поведения, не совместно используя реализации.
Переменная, чья объявленный типом интерфейсный тип, может иметь как его значение ссылка на любой экземпляр класса, который реализует указанный интерфейс. Не достаточно, что класс, оказывается, реализует все абстрактные методы интерфейса; класс или один из его суперклассов, как должны фактически объявлять, реализуют интерфейс, или иначе класс, как полагают, не реализует интерфейс.
InterfaceDeclaration: InterfaceModifiersopt interface Identifier ExtendsInterfacesopt InterfaceBodyИдентификатор в интерфейсном объявлении определяет имя интерфейса. Ошибка времени компиляции происходит, если у интерфейса есть то же самое простое имя как какой-либо из его классов включения или интерфейсов.
InterfaceModifiers: InterfaceModifier InterfaceModifiers InterfaceModifier InterfaceModifier: one of public protected private abstract static strictfpОбщественность модификатора доступа обсуждается в §6.6. Не все модификаторы применимы ко всем видам интерфейсных объявлений. Модификаторы доступа, защищенные и частные, принадлежат только задействованным интерфейсам в пределах непосредственно объявления класса включения (§8.5) и обсуждаются в §8.5.1. Статичный модификатор доступа принадлежит только задействованным интерфейсам (§8.5, §9.5). Ошибка времени компиляции происходит, если тот же самый модификатор появляется не раз в интерфейсном объявлении.
abstract
Интерфейсыabstract
. Этот модификатор является устаревшим и не должен использоваться в новых программах.strictfp
Интерфейсыstrictfp
модификатор должен сделать все float
или double
выражения в пределах интерфейсного объявления быть явно строгим FP (§15.4).
Это подразумевает, что все вложенные типы, объявленные в интерфейсе, неявно strictfp
.
extends
пункт обеспечивается, тогда объявляемый интерфейс расширяет каждый из других именованных интерфейсов и поэтому наследовал типы элемента, методы, и константы каждого из других именованных интерфейсов. Эти другие именованные интерфейсы являются прямыми суперинтерфейсами объявляемого интерфейса. Любой класс это implements
объявленный интерфейс, как также полагают, реализует все интерфейсы что этот интерфейс extends
.
ExtendsInterfaces: extends InterfaceType ExtendsInterfaces , InterfaceTypeСледующее повторяется от §4.2, чтобы сделать представление здесь более четким:
InterfaceType: TypeNameКаждый InterfaceType в
extends
пункт интерфейсного объявления должен назвать доступный интерфейсный тип; иначе ошибка времени компиляции происходит.
Интерфейс I непосредственно зависит от типа T, если T упоминается в extends
пункт я или как суперинтерфейс или как спецификатор в пределах суперинтерфейсного имени. Интерфейс I зависит от ссылочного типа T, если какое-либо из следующих условий содержит:
В то время как каждый класс является расширением класса Object
, нет никакого единственного интерфейса, которого все интерфейсы являются расширениями.
Суперинтерфейсное отношение является переходным закрытием прямого суперинтерфейсного отношения. Интерфейсный K является суперинтерфейсом интерфейса I, если любое из следующего является истиной:
InterfaceBody:
{ InterfaceMemberDeclarationsopt }
InterfaceMemberDeclarations:
InterfaceMemberDeclaration
InterfaceMemberDeclarations InterfaceMemberDeclaration
InterfaceMemberDeclaration:
ConstantDeclaration
AbstractMethodDeclaration
ClassDeclaration
InterfaceDeclaration
;
Контекст объявления элемента м. объявил в или наследовался интерфейсным типом, я - все тело меня, включая любые объявления вложенного типа.public
. Они доступны вне пакета, где интерфейс объявляется, если интерфейс также объявляется public
или protected
, в соответствии с правилами §6.6.
throws
пункт t, соответствующий каждому общедоступному методу экземпляра м. с подписью s, возвратите тип r, и throws
пункт t, объявленный в Object
, если метод с той же самой подписью, тем же самым типом возврата, и совместимым throws
пункт явно объявляется интерфейсом. throws
пункт.Интерфейс наследовался от интерфейсов, которые он расширяет, все элементы тех интерфейсов, за исключением полей, классов, и интерфейсов, которые он скрывает и методы, которые он переопределяет.
ConstantDeclaration: ConstantModifiersopt Type VariableDeclarators ConstantModifiers: ConstantModifierКаждое полевое объявление в теле интерфейса неявноConstantModifiers ConstantModifer
ConstantModifier: one of public static final
public
, static
, и final
. Разрешается избыточно определить любые из этих модификаторов для таких полей.Если интерфейс объявляет поле с определенным именем, то объявление того поля, как говорят, скрывает любого и все доступные объявления полей с тем же самым именем в суперинтерфейсах интерфейса.
Это - ошибка времени компиляции для тела интерфейсного объявления, чтобы объявить два поля с тем же самым именем.
Для интерфейса возможно наследовать больше чем одно поле с тем же самым именем (§8.3.3.3). Такая ситуация сам по себе не вызывает ошибку времени компиляции. Однако, любая попытка в пределах тела интерфейса, чтобы обратиться к любому полю его простым именем приведет к ошибке времени компиляции, потому что такая ссылка неоднозначна.
Могло бы быть несколько путей, которыми то же самое полевое объявление могло бы быть наследовано от интерфейса. В такой ситуации поле, как полагают, наследовано только однажды, и это может быть упомянуто его простым именем без неоднозначности.
Ошибка времени компиляции происходит, если выражение инициализации для интерфейсного поля содержит ссылку простым именем к тому же самому полю или к другому полю, объявление которого происходит дословно позже в том же самом интерфейсе.
причины две ошибки времени компиляции, потому чтоinterface Test { float f = j; int j = 1; int k = k+1; }
j
упоминается в инициализации f
прежде j
объявляется и потому что инициализация k
обращается к k
непосредственно.
Одна тонкость здесь - то, что во время выполнения поля, которые инициализируются с постоянными величинами времени компиляции, инициализируются сначала. Это применяется также к static
final
поля в классах (§8.3.2.1). Это означает, в частности что у этих полей, как никогда будут наблюдать, не будет своих начальных значений по умолчанию (§4.5.5), даже окольными программами. См. §12.4.2 и §13.4.8 для большего количества обсуждения.
Если ключевое слово this
(§15.8.3) или ключевое слово super
(15.11.2, 15.12), происходит в выражении инициализации для поля интерфейса, затем если возникновение не в пределах тела анонимного класса (§15.9.5), ошибка времени компиляции происходит.
интерфейс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: AbstractMethodModifiersopt ResultType MethodDeclarator Throwsopt ; AbstractMethodModifiers: AbstractMethodModifier AbstractMethodModifiers AbstractMethodModifier AbstractMethodModifier: one of public abstractМодификатор доступа
public
обсуждается в §6.6. Ошибка времени компиляции происходит, если тот же самый модификатор появляется не раз в абстрактном объявлении метода.
Каждое объявление метода в теле интерфейса неявно abstract
, таким образом, его тело всегда представляется точкой с запятой, не блоком.
Каждое объявление метода в теле интерфейса неявно public
.
Для совместимости с более старыми версиями платформы Java это разрешается, но обескураживается, как стиль, чтобы избыточно определить abstract
модификатор для методов объявляется в интерфейсах.
Это разрешается, но строго обескураживается как стиль, чтобы избыточно определить public
модификатор для интерфейсных методов.
Отметьте, что метод, объявленный в интерфейсе, не должен быть объявлен static
, или ошибка времени компиляции происходит, потому что static
методы не могут быть abstract
.
Отметьте, что метод, объявленный в интерфейсе, не должен быть объявлен strictfp
или native
или synchronized
, или ошибка времени компиляции происходит, потому что те ключевые слова описывают свойства реализации, а не интерфейсные свойства. Однако, метод, объявленный в интерфейсе, может быть реализован методом, который объявляется strictfp
или native
или synchronized
в классе, который реализует интерфейс.
Это - ошибка времени компиляции для тела интерфейса, чтобы объявить, явно или неявно, два метода с той же самой подписью (имя, число параметров, и типы любых параметров) (§8.4.2). Однако, интерфейс может наследовать несколько методов с той же самой подписью (§9.4.1).
Отметьте, что метод, объявленный в интерфейсе, не должен быть объявлен 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
с тремя различными подписями, двумя из них объявленный и один наследованный. Любой не -abstract
класс, который реализует интерфейс RealPointInterface
должен обеспечить реализации всех трех сигнатур методов.static
и public
.Если тип элемента, объявленный с простым именем C, непосредственно включается в пределах объявления интерфейса с полностью определенным именем N, то у типа элемента есть полностью определенное имя Северная Каролина.
Если интерфейс объявляет тип элемента с определенным именем, то объявление того поля, как говорят, скрывает любого и все доступные объявления типов элемента с тем же самым именем в суперинтерфейсах интерфейса.
Интерфейс может наследовать два или больше описания типа с тем же самым именем. Ошибка времени компиляции происходит на любой попытке обратиться к любому двусмысленно наследованному классу или интерфейсу его простым именем. Если то же самое описание типа наследовано от интерфейса разнообразными путями, класс или интерфейс, как полагают, наследованы только однажды; это может быть упомянуто его простым именем без неоднозначности.
Содержание | Предыдущий | Следующий | Индекс | Спецификация языка Java Второй Выпуск |