Главная страница

АБОБА. Справочник по программированию на Java Методическое пособие


Скачать 242.41 Kb.
НазваниеСправочник по программированию на Java Методическое пособие
АнкорАБОБА
Дата20.02.2022
Размер242.41 Kb.
Формат файлаdocx
Имя файла12642_java_method_1.docx
ТипСправочник
#368066
страница52 из 67
1   ...   48   49   50   51   52   53   54   55   ...   67

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


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

доступ 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. При реализации метода интерфейса он должен быть объявлен как public.

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

class Client implements Callback {

// Реализует интерфейс Callback

public void callback(int p) {

System.out.println("Метод callback, вызванный со значением " + p);

}

void nonIfaceMeth() {

System.out.println("Классы, которые реализуют интерфейсы" +

"могут определять также и другие члены.");

}

}

Доступ к реализациям через ссылки на интерфейсы


Переменные можно объявлять как объектные ссылки, которые используют тип интерфейса, а не тип класса. Посредством такой переменной можно ссылаться на любой экземпляр любого класса, реализующего объявленный интерфейс. При вызове метода с помощью одной из таких ссылок выбор нужной версии будет производиться в зависимости от конкретного экземпляра интерфейса, на который выполняется ссылка. Это – одна из главных особенностей интерфейсов. Поиск выполняемого метода осуществляется динамически во время выполнения, что позволяет создавать классы позже, чем код, который вызывает методы по отношению к этим классам. Диспетчеризация кода может выполняться посредством интерфейса без необходимости наличия каких-либо сведений о “вызывающем”. Этот процесс аналогичен использованию ссылки на суперкласс для доступа к объекту подкласса.

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

В следующем примере метод callback() вызывается через ссылочную переменную интерфейса:

class TestIface {

public static void main(String args[]) {

Callback c = new Client();

c.callback(42);

}

}

Эта программа создает следующий вывод:

Метод callback, вызванный со значением 42

Обратите внимание, что хотя переменная c объявлена с типом интерфейса Callback, ей был присвоен экземпляр класса Client. Хотя переменную c можно использовать для доступа к методу callback(), она не имеет доступа к каким-то другим членам класса Client. Ссылочная переменная интерфейса располагает сведениями только о тех методах, которые объявлены ее объявлением interface. Таким образом, переменная c не может применяться для доступа к методу nonIfaceMeth(), поскольку она объявлена классом Client, а не классом Callback.

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

// Еще одна реализация интерфейса Callback.

class AnotherClient implements Callback {

// Реализация интерфейса Callback

BookNew_JAVA-7.indb 226 02.06.2007 1:06:57

Глава 9. Пакеты и интерфейсы 227

public void callback(int p) {

System.out.println("Еще одна версия callback");

System.out.println("p в квадрате равно " + (p*p));

}

}

Теперь проверим работу следующего класса:

class TestIface2 {

public static void main(String args[]) {

Callback c = new Client();

AnotherClient ob = new AnotherClient();

c.callback(42);

c = ob; // теперь c ссылается на объект AnotherClient

c.callback(42);

}

}

Эта программа создает следующий вывод:

callback вызванный со значением 42

Еще одна версия callback

p в квадрате равно 1764

Как видите, вызываемая версия метода callback() определяется типом объекта, на который переменная c ссылается во время выполнения. Представленный пример очень прост, поэтому вскоре мы приведем еще один, более реальный пример.
1   ...   48   49   50   51   52   53   54   55   ...   67


написать администратору сайта