Java Урок 40: НАСЛЕДОВАНИЕ, интерфейсы

Применение ключевого слова interface позволяет полностью абстрагировать интерфейс класса от его реализации. То есть с использованием ключевого слова interface можно задать действия, которые должен выполнять класс, но не то, как именно он должен это делать.

Скачать исходники для статьи можно ниже

Синтаксически интерфейсы аналогичны классам, но не содержат переменных экземпляров, а объявления их методов не содержат тела метода.

На практике это означает, что можно объявлять интерфейсы, которые не делают никаких допущений относительно их реализации. Как только
интерфейс определен, его может реализовать любое количество классов.
Кроме того, один класс может реализовать любое количество интерфейсов.

Чтобы реализовать интерфейс, класс должен создать полный набор методов, определенных интерфейсом. Однако каждый класс может определять нюансы своей реализации данного интерфейса.

Ключевое слово interface позволяет в полной мере использовать концепцию полиморфизма под названием “один интерфейс, несколько методов”.

Интерфейсы предназначены для поддержки динамического разрешения методов во время выполнения. Обычно, чтобы вызов метода мог выполняться из одного класса в другом, оба класса должны присутствовать во время компиляции, дабы компилятор Java мог проверить совместимость сигнатур методов.

Само по себе это требование создает статическую и нерасширяемую среду обработки классов.

В такой системе функциональные возможности неизбежно передаются по иерархии классов все выше и выше, в результате чего механизмы будут становиться доступными все большему количеству подклассов. Интерфейсы предназначены для предотвращения этой проблемы.

Они изолируют определение метода или набора методов от иерархии наследования.

Поскольку иерархия интерфейсов не совпадает с иерархией классов, классы, никак не связанные между собой в иерархии классов, могут реализовать один и тот же интерфейс. Именно здесь возможности
интерфейсов проявляются наиболее полно.

Определение интерфейса

Во многом определение интерфейса подобно определению класса. Упрощенная общая форма интерфейса имеет следующий вид:

доступ interface имя {
возвращаемый_тип имя_метода1(список_параметров) ;
возвращаемый_тип имя_метода2 (список_параметров) ;
тип имя_конечной_переменной1 = значение;
тип имя_конечной_переменной2 = значение;
// . . .
возвращаемый_ тип имя_методаN ( список_параметров) ;
тип имя_конечной_переменнойN = значение;
}

Если определение не содержит никакого модификатора доступа, используется доступ по умолчанию и интерфейс доступен только другим членам того пакета, в котором он объявлен.

Если интерфейс объявлен как public, он может быть использован любым другим кодом. В этом случае интерфейс должен быть единственным
открытым интерфейсом, объявленным в файле, и имя файла должно совпадать с именем интерфейса.

Имя — имя интерфейса, которым может быть любой допустимый идентификатор.

Обратите внимание на то, что объявляемые методы не содержат тел. Их объявления завершаются списком параметров, за которым следует символ “точка с запятой”. По сути, они представляют собой абстрактные
методы. Ни один из указанных внутри интерфейса методов не может обладать никакой заданной по умолчанию реализацией. Каждый класс, который включает в себя интерфейс, должен реализовать все его методы.

Переменные могут быть объявлены внутри объявлений интерфейсов. Они неявно объявляются как final и static, т.е. реализующий класс не может их изменять.
Кроме того, они должны быть также инициализированы. Все методы и переменные неявно объявляются как public.

Ниже приведен пример определения интерфейса. В нем объявляется простой
интерфейс, который содержит один метод callback(), принимающий единственный целочисленный параметр.

interface Callback {
   void callback(int param);
}

Реализация интерфейсов

Как только интерфейс определен, его может реализовать один или несколько классов.
Чтобы реализовать интерфейс, в определение класса потребуется включить
конструкцию implements, а затем создать методы, определенные интерфейсом.
Общая форма класса, который содержит выражение implements, имеет следующий вид.

доступ class имя_класса [extends суперкласс]
[implements интерфейс [,интерфейс...]] {
   // тело_класса
}

Если класс реализует более одного интерфейса, имена интерфейсов разделяются запятыми. Если класс реализует два интерфейса, которые объявляют один и тот же метод, то один и тот же метод будет использоваться клиентами любого интерфейса.

Методы, которые реализуют интерфейс, должны быть объявлены
как public. Кроме того, сигнатура типа реализующего метода должна в точности совпадать с сигнатурой типа, указанной в определении interface.

Рассмотрим небольшой пример класса, который реализует приведенный ранее интерфейс Callback.

class Client implements Callback {
   // Реализует интерфейс Callback
   public void callback(int p) {
      System.out.println("Метод callback, вызванный со значением " + p) ;
   }
}

Обратите внимание на то, что метод callback() объявлен с использованием модификатора доступа public.

Вполне допустима и достаточно распространена ситуация, когда классы, которые реализуют интерфейсы, определяют собственные дополнительные члены.
Например, следующая версия класса Client реализует метод callback() и добавляет метод nonlnf aceMeth().

class Client implements Callback {
   // Реализует интерфейс Callback
   public void callback(int p) {
      System.out.println("Метод callback, вызванный со значением " + P) ;
   }
   void nonIfaceMeth() {
      System.out.println("Классы, которые реализуют интерфейсы" + "могут определять также и другие члены.");
   }
}

Введите свой email адрес для того, чтобы подписаться на мой блог:


knopkisoc

Добавить комментарий