Обобщенные интерфейсы

В дополнение к обобщенным классам и методам вы можете объявлять обобщенные интерфейсы. Обобщенные интерфейсы специфицируются так же, как и обобщенные классы. Ниже показан пример. В нем создается интерфейс MinMax, объявляющий методы min () и max (), которые, как ожидается, должны возвращать минимальное и максимальное значения из некоторого множества объектов.

// Пример обобщенного интерфейса.
// Интерфейс Min/Max.
interface MinMax> {
T min () ;
T max() ;
}
// Реализация MinMax
class MyClass>
implements MinMax {
T[] vals;
MyClass (ТП o) {
vals = o; }
// Возвращает минимальное значение из vals.
public T min () {
T v = vals[0];
for(int i=l; i < vals.length; i++)
if(vals[i].compareTo(v) < 0) v=vals[i];
return v;
}
// Возвращает максимальное значение из vals.
public T max() {
T v = vals[0] ;
for(int i=l; i < vals.length; i++)
if (vals [i] . compareTo (v) > 0) v = vals[i];
return v;
}
}
class GenlFDemo {
public static void main(String args[]) {
Integer inums[] = {3, 6, 2, 8, 6 };
Character chs[] = ('b', 'r\ 'p', 'w' };
MyClass iob = new MyClass(inums);
MyClass cob = new MyClass(chs);
System.out.println("Максимальное значение в inums: " + iob.maxO);
System.out.println("Минимальное значение в inums: " + iob.minO);
System.out.println("Максимальное значение в chs: " + cob.maxO);
System.out.println("Минимальное значение в chs: " + cob.min());
}
}

Результат работы этой программы:

Максимальное значение в inums: 8
Минимальное значение в inums: 2
Максимальное значение в chs: w
Минимальное значение в chs: b

Хотя большинство аспектов этой программы просты для понимания, некоторые ключевые моменты следует пояснить. Во-первых, обратите внимание на то, как объявлен MinMax:

interface MinMax> {

В общем случае, обобщенный интерфейс объявляется так же, как и обобщенный класс. В этом случае тип параметра Т имеет верхнюю границу Comparable — интерфейс, определенный в java.lang. Класс, который реализует Comparable, определяет объекты, которые могут быть упорядочены. То есть требование, чтобы т был ограничен сверху Comparable, гарантирует, что MinMax может быть использован только с объектами, которые могут сравниваться между собой. Отметим, что Comparable сам по себе также является обобщенным интерфейсом (он был преобразован в обобщенную форму в JDK 5). Он принимает параметр типа объектов, которые должны сравниваться.

Далее MinMax реализует класс MyClass. Вот как выглядит объявление класса MyClass:

class MyClass> implements MinMax {

Обратите особое внимание на способ, которым параметр типа Т объявлен в MyClass и затем передан MinMax. Поскольку MinMax требует типа, который реализует Comparable, реализующий класс (в данном случае — MinMax) должен специфицировать то же ограничение. Более того, однажды установленное, это ограничение уже не нужно повторять в операторе implements. Фактически так поступать некорректно. Например, следующая строка неверна и не может быть скомпилирована:

// Это не правильно!
class MyClass>
implements MinMax> {

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

Вообще если класс реализует обобщенный интерфейс, то такой класс также должен быть обобщенным, по крайней мере, в тех пределах, где он принимает параметр типа, переданный интерфейсу. Например, следующая попытка объявления MyClass вызовет ошибку:

class MyClass implements MinMax {
// Неверно!

Поскольку MyClass не объявляет параметра, нет способа передать его MinMax. В этом случае идентификатор Т просто неизвестен, и компилятор выдаст ошибку. Конечно, если класс реализует специфический тип обобщенного интерфейса, как показано ниже:

class MyClass implements MinMax {
// OK

то реализующий класс не обязан быть обобщенным.

Обобщенный интерфейс представляет два преимущества. Во-первых, он может быть реализован для разных типов данных. Во-вторых, он позволяет включить ограничения на типы данных, для которых он может быть реализован. В примере MinMax вместо Т могут быть подставлены только типы, совместимые с Comparable.

Вот общий синтаксис обобщенного интерфейса:

interface имя интерфейса<список параметров типов> {
// ...

Здесь список_параметров_типов — разделенный запятыми список параметров типов. Когда реализуется обобщенный интерфейс, вы должны специфицировать аргументы типов, как показано ниже:

class имя_класса<список_параметров_типов> implements имя_интерфейса<список_аргументов_типов> {